smstools 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4180ff46eb40f9d709cf9895d1dc493aeec4203c
4
- data.tar.gz: cba4fd705516f2418dfae93ce3732231e30faba5
3
+ metadata.gz: b0c466ba58b15a65599eb4abbaac0d22a6f82ac5
4
+ data.tar.gz: 416a9721a3ada4264dee86f28e1af344b24a8dbf
5
5
  SHA512:
6
- metadata.gz: b3b26b73c00f2acbb9e107ecc24738b97a713a3579c685339226b9ba369c0d2080ff7b40357a472c0dc9ebe41bca0f8ed38e28cd132242ce7ed3e514a78d69c3
7
- data.tar.gz: 9b7a0e6a64fdaec4f8f05130dc3b4ac735f2848fddfd1bbd8d274ec2b6e9781fcdb993ef121357e77f6b4c486508a067e6480516a72fd33d7c28007397f0fde5
6
+ metadata.gz: 1946b4d7493dfb0bd01d699f13ccd2ee7a2498daeb80b2f5070273031860e1189223837a785e8aca2c6e71bfcc63210dd7632bf8d105a80537b4264edf417df6
7
+ data.tar.gz: 2ca97dbb11cf51eb4493f152303dc5d81b6286ee83b4d7921fcaa01dcc195d0052d1d5dda7ae3b390637ce2d7285af23604c5f6822324b8a87a45e1316493b15
data/README.md CHANGED
@@ -1,23 +1,70 @@
1
1
  # Sms Tools
2
2
 
3
- A small collection of useful Ruby and JavaScript classes implementing often
4
- needed functionality for dealing with SMS messages.
3
+ A small collection of Ruby and JavaScript classes implementing often needed functionality for
4
+ dealing with SMS messages.
5
5
 
6
- The gem is also a Rails engine and using it in your Rails app will allow you
7
- to also use the JavaScript classes via the asset pipeline.
6
+ The gem can also be used in a Rails application as an engine. It integrates with the asset pipeline
7
+ and gives you access to some clinet-side SMS manipulation functionality.
8
8
 
9
9
  ## Features
10
10
 
11
11
  The following features are available on both the server side and the client
12
12
  side:
13
13
 
14
- - Detection of the most optimal encoding for sending an SMS message (GSM 7-bit
15
- or Unicode).
16
- - Correctly determining the message's length according to the most optimal
17
- encoding.
14
+ - Detection of the most optimal encoding for sending an SMS message (GSM 7-bit or Unicode).
15
+ - Correctly determining a message's length in the most optimal encoding.
18
16
  - Concatenation detection and concatenated message parts counting.
19
17
 
20
- And more.
18
+ The following can be accomplished only on the server with Ruby:
19
+
20
+ - Converting a UTF-8 string to a GSM 7-bit encoding and vice versa.
21
+ - Detecting if a UTF-8 string can be safely represented in a GSM 7-bit encoding.
22
+ - Detection of double-byte chars in the GSM 7-bit encoding.
23
+
24
+ And possibly more.
25
+
26
+ ### Note on the GSM encoding
27
+
28
+ All references to the "GSM" encoding or the "GSM 7-bit alphabet" in this text actually refer to the
29
+ [GSM 03.38 spec](http://en.wikipedia.org/wiki/GSM_03.38) and [its latest
30
+ version](ftp://ftp.unicode.org/Public/MAPPINGS/ETSI/GSM0338.TXT), as defined by the Unicode
31
+ consortium.
32
+
33
+ This encoding is the most widely used one when sending SMS messages.
34
+
35
+ ### Note regarding non-ASCII symbols from the GSM encoding
36
+
37
+ The GSM 03.38 encoding is used by default. This standard defines a set of
38
+ symbols which can be encoded in 7-bits each, thus allowing up to 160 symbols
39
+ per SMS message (each SMS message can contain up to 140 bytes of data).
40
+
41
+ This standard covers most of the ASCII table, but also includes some non-ASCII
42
+ symbols such as `æ`, `ø` and `å`. If you use these in your messages, you can
43
+ still send them as GSM encoded, having a 160-symbol limit. This is technically
44
+ correct.
45
+
46
+ In reality, however, some SMS routes have problems delivering messages which
47
+ contain such non-ASCII symbols in the GSM encoding. The special symbols might
48
+ be omitted, or the message might not arrive at all.
49
+
50
+ Thus, it might be safer to just send messages in Unicode if the message's text
51
+ contains any non-ASCII symbols. This is not the default as it reduces the max
52
+ symbols count to 70 per message, instead of 160, and you might not have any
53
+ issues with GSM-encoded messages. In case you do, however, you can turn off
54
+ support for the GSM encoding and just treat messages as Unicode if they contain
55
+ non-ASCII symbols.
56
+
57
+ In case you decide to do so, you have to specify it in both the Ruby and the
58
+ JavaScript part of the library, like so:
59
+
60
+ #### In Ruby
61
+
62
+ SmsTools.use_gsm_encoding = false
63
+
64
+ #### In Javascript
65
+
66
+ //= require sms_tools
67
+ SmsTools.use_gsm_encoding = false;
21
68
 
22
69
  ## Installation
23
70
 
@@ -33,32 +80,99 @@ Or install it yourself as:
33
80
 
34
81
  $ gem install smstools
35
82
 
83
+ If you're using the gem in Rails, you may also want to add the following to your `application.js`
84
+ manifest file to gain access to the client-side features:
85
+
86
+ //= require sms_tools
87
+
36
88
  ## Usage
37
89
 
38
90
  The gem consists of both server-side (Ruby) and client-side classes. You can
39
- use either one.
91
+ use either.
40
92
 
41
93
  ### Server-side code
42
94
 
43
- If you use the gem in Rails or via Bundler, just use the appropriate class,
44
- such as `SmsTools::EncodingDetection` or `SmsTools::GsmEncoding`.
95
+ First make sure you have installed the gem and have required the appropriate files.
45
96
 
46
- #### `EncodingDetection`
47
- #### `GsmEncoding`
97
+ #### Encoding detection
98
+
99
+ The `SmsTools::EncodingDetection` class provides you with a few simple methods to detect the most
100
+ optimal encoding for sending an SMS message, to correctly caclulate its length in that encoding and
101
+ to see if the text would need to be concatenated or will fit in a single message.
102
+
103
+ Here is an example with a non-concatenated message which is best encoded in the GSM 7-bit alphabet:
104
+
105
+ ```ruby
106
+ sms_text = 'Text in GSM 03.38: ÄäøÆ with a double-byte char: ~ '
107
+ sms_encoding = SmsTools::EncodingDetection.new sms_text
108
+
109
+ sms_encoding.gsm? # => true
110
+ sms_encoding.unicode? # => false
111
+ sms_encoding.length # => 52 (because of the double-byte char)
112
+ sms_encoding.concatenated? # => false
113
+ sms_encoding.concatenated_parts # => 1
114
+ sms_encoding.encoding # => :gsm
115
+ ```
116
+
117
+ Here's another example with a concatenated Unicode message:
118
+
119
+ ```ruby
120
+ sms_text = 'Я' * 90
121
+ sms_encoding = SmsTools::EncodingDetection.new sms_text
122
+
123
+ sms_encoding.gsm? # => false
124
+ sms_encoding.unicode? # => true
125
+ sms_encoding.length # => 90
126
+ sms_encoding.concatenated? # => true
127
+ sms_encoding.concatenated_parts # => 2
128
+ sms_encoding.encoding # => :unicode
129
+ ```
130
+
131
+ You can check the specs for this class for more examples.
132
+
133
+ #### GSM 03.38 encoding conversion
134
+
135
+ The `SmsTools::GsmEncoding` class can be used to check if a given UTF-8 string can be fully
136
+ represented in the GSM 03.38 encoding as well as to convert from UTF-8 to GSM 03.38 and vice-versa.
137
+
138
+ The main API this class provides is the following:
139
+
140
+ ```ruby
141
+ SmsTools::GsmEncoding.valid? message_text_in_utf8 # => true or false
142
+
143
+ SmsTools::GsmEncoding.from_utf8 utf8_encoded_string # => a GSM 03.38 encoded string
144
+ SmsTools::GsmEncoding.to_utf8 gsm_encoded_string # => an UTF-8 encoded string
145
+ ```
146
+
147
+ Check out the source code of the class to find out more.
48
148
 
49
149
  ### Client-side code
50
150
 
51
- If you're using the gem in Rails 3.x or newer, you can just add the following
52
- to your `application.js` file to gain access to the JavaScript classes:
151
+ If you're using the gem in Rails 3.1 or newer, you can gain access to the `SmsTools.Message` class.
152
+ It's interface is similar to the one of `SmsTools::EncodingDetection`. Here is an example in
153
+ CoffeeScript:
154
+
155
+ ```coffeescript
156
+ message = new SmsTools.Message 'The text of the message: ~'
157
+
158
+ message.encoding # => 'gsm'
159
+ message.length # => 27
160
+ message.concatenatedPartsCount # => 1
161
+ ```
53
162
 
54
- #= require 'sms_tools/all'
163
+ You can also check how long can this message be in the current most optimal encoding, if we want to
164
+ limit the number of concatenated messages we will allow to be sent:
55
165
 
56
- Or require only the files you need:
166
+ ```coffeescript
167
+ maxConcatenatedPartsCount = 2
168
+ message.maxLengthFor(maxConcatenatedPartsCount) # => 306
169
+ ```
57
170
 
58
- #= require 'sms_tools/message'
171
+ This allows you to have a dynamic instead of a fixed length limit, for when you use a non-GSM 03.38
172
+ symbol in your text, your message length limit decreases significantly.
59
173
 
60
- Note that this assumes you're using the asset pipeline. You need to have a
61
- CoffeeScript preprocessor set up.
174
+ Note that to use this client-side code, a Rails application with an active asset pipeline is
175
+ assumed. It might be possible to use it in other setups as well, but you're on your own there.
62
176
 
63
177
  ## Contributing
64
178
 
@@ -2,6 +2,9 @@ window.SmsTools ?= {}
2
2
 
3
3
  class SmsTools.Message
4
4
  maxLengthForEncoding:
5
+ ascii:
6
+ normal: 160
7
+ concatenated: 153
5
8
  gsm:
6
9
  normal: 160
7
10
  concatenated: 153
@@ -20,6 +23,7 @@ class SmsTools.Message
20
23
  '€': true
21
24
  '\\': true
22
25
 
26
+ asciiPattern: /^[\x00-\x7F]*$/
23
27
  gsmEncodingPattern: /^[0-9a-zA-Z@Δ¡¿£_!Φ"¥Γ#èΛ¤éΩ%ùΠ&ìΨòΣçΘΞ:Ø;ÄäøÆ,<Ööæ=ÑñÅß>Üüåɧà€~ \$\.\-\+\(\)\*\\\/\?\|\^\}\{\[\]\'\r\n]*$/
24
28
 
25
29
  constructor: (@text) ->
@@ -33,8 +37,19 @@ class SmsTools.Message
33
37
 
34
38
  concatenatedPartsCount * @maxLengthForEncoding[@encoding][messageType]
35
39
 
40
+ use_gsm_encoding: ->
41
+ if SmsTools['use_gsm_encoding'] == undefined
42
+ true
43
+ else
44
+ SmsTools['use_gsm_encoding']
45
+
36
46
  _encoding: ->
37
- if @gsmEncodingPattern.test(@text) then 'gsm' else 'unicode'
47
+ if @asciiPattern.test(@text)
48
+ 'ascii'
49
+ else if @use_gsm_encoding() and @gsmEncodingPattern.test(@text)
50
+ 'gsm'
51
+ else
52
+ 'unicode'
38
53
 
39
54
  _concatenatedPartsCount: ->
40
55
  encoding = @encoding
@@ -45,9 +60,9 @@ class SmsTools.Message
45
60
  else
46
61
  parseInt Math.ceil(length / @maxLengthForEncoding[encoding].concatenated), 10
47
62
 
48
- # Returns the number of symbols, which the given text will take up in an SMS
49
- # message, taking into account any double-space symbols in the GSM 03.38
50
- # encoding.
63
+ # Returns the number of symbols which the given text will eat up in an SMS
64
+ # message, taking into account any double-space symbols in the GSM 03.38
65
+ # encoding.
51
66
  _length: ->
52
67
  length = @text.length
53
68
 
data/lib/sms_tools.rb CHANGED
@@ -5,3 +5,15 @@ require 'sms_tools/gsm_encoding'
5
5
  if defined?(::Rails) and ::Rails.version >= '3.1'
6
6
  require 'sms_tools/rails/engine'
7
7
  end
8
+
9
+ module SmsTools
10
+ class << self
11
+ def use_gsm_encoding?
12
+ @use_gsm_encoding.nil? ? true : @use_gsm_encoding
13
+ end
14
+
15
+ def use_gsm_encoding=(value)
16
+ @use_gsm_encoding = value
17
+ end
18
+ end
19
+ end
@@ -3,6 +3,10 @@ require 'sms_tools/gsm_encoding'
3
3
  module SmsTools
4
4
  class EncodingDetection
5
5
  MAX_LENGTH_FOR_ENCODING = {
6
+ ascii: {
7
+ normal: 160,
8
+ concatenated: 153,
9
+ },
6
10
  gsm: {
7
11
  normal: 160,
8
12
  concatenated: 153,
@@ -20,7 +24,18 @@ module SmsTools
20
24
  end
21
25
 
22
26
  def encoding
23
- @encoding ||= GsmEncoding.valid?(text) ? :gsm : :unicode
27
+ @encoding ||=
28
+ if text.ascii_only?
29
+ :ascii
30
+ elsif SmsTools.use_gsm_encoding? and GsmEncoding.valid?(text)
31
+ :gsm
32
+ else
33
+ :unicode
34
+ end
35
+ end
36
+
37
+ def ascii?
38
+ encoding == :ascii
24
39
  end
25
40
 
26
41
  def gsm?
@@ -49,9 +64,9 @@ module SmsTools
49
64
  concatenated_parts * MAX_LENGTH_FOR_ENCODING[encoding][message_type]
50
65
  end
51
66
 
52
- # Returns the number of symbols, which the given text will take up in an SMS
53
- # message, taking into account any double-space symbols in the GSM 03.38
54
- # encoding.
67
+ # Returns the number of symbols which the given text will eat up in an SMS
68
+ # message, taking into account any double-space symbols in the GSM 03.38
69
+ # encoding.
55
70
  def length
56
71
  length = text.length
57
72
  length += text.chars.count { |char| GsmEncoding.double_byte?(char) } if gsm?
@@ -1,3 +1,3 @@
1
1
  module SmsTools
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'sms_tools/encoding_detection'
2
+ require 'sms_tools'
3
3
 
4
4
  describe SmsTools::EncodingDetection do
5
5
  it "exposes the original text as a method" do
@@ -7,27 +7,49 @@ describe SmsTools::EncodingDetection do
7
7
  end
8
8
 
9
9
  describe "encoding" do
10
- it "defaults to GSM encoding for empty messages" do
11
- detection_for('').encoding.must_equal :gsm
10
+ it "defaults to ASCII encoding for empty messages" do
11
+ detection_for('').encoding.must_equal :ascii
12
12
  end
13
13
 
14
- it "returns GSM as encoding for simple ASCII text" do
15
- detection_for('foo bar baz').encoding.must_equal :gsm
14
+ it "returns ASCII as encoding for simple ASCII text" do
15
+ detection_for('foo bar baz').encoding.must_equal :ascii
16
16
  end
17
17
 
18
18
  it "returns GSM as encoding for special symbols defined in GSM 03.38" do
19
19
  detection_for('09azAZ@Δ¡¿£_!Φ"¥Γ#èΛ¤éΩ%ùΠ&ìΨòΣçΘΞ:Ø;ÄäøÆ,<Ööæ=ÑñÅß>Üüåɧà€~').encoding.must_equal :gsm
20
20
  end
21
21
 
22
- it "returns GSM as encoding for puntucation and newline symbols" do
23
- detection_for('Foo bar {} [baz]! Larodi $5. What else?').encoding.must_equal :gsm
24
- detection_for("Spaces and newlines are GSM 03.38, too: \r\n").encoding.must_equal :gsm
22
+ it "returns ASCII as encoding for puntucation and newline symbols" do
23
+ detection_for('Foo bar {} [baz]! Larodi $5. What else?').encoding.must_equal :ascii
24
+ detection_for("Spaces and newlines are GSM 03.38, too: \r\n").encoding.must_equal :ascii
25
25
  end
26
26
 
27
27
  it "returns Unicode when non-GSM Unicode symbols are used" do
28
28
  detection_for('Foo bar лароди').encoding.must_equal :unicode
29
29
  detection_for('∞').encoding.must_equal :unicode
30
30
  end
31
+
32
+ describe 'with SmsTools.use_gsm_encoding = false' do
33
+ before do
34
+ SmsTools.use_gsm_encoding = false
35
+ end
36
+
37
+ after do
38
+ SmsTools.use_gsm_encoding = true
39
+ end
40
+
41
+ it "returns Unicode as encoding for special symbols defined in GSM 03.38" do
42
+ detection_for('09azAZ@Δ¡¿£_!Φ"¥Γ#èΛ¤éΩ%ùΠ&ìΨòΣçΘΞ:Ø;ÄäøÆ,<Ööæ=ÑñÅß>Üüåɧà€~').encoding.must_equal :unicode
43
+ end
44
+
45
+ it 'returns ASCII for simple ASCII text' do
46
+ detection_for('Hello world.').encoding.must_equal :ascii
47
+ end
48
+
49
+ it "defaults to ASCII encoding for empty messages" do
50
+ detection_for('').encoding.must_equal :ascii
51
+ end
52
+ end
31
53
  end
32
54
 
33
55
  describe "message length" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smstools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitar Dimitrov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-17 00:00:00.000000000 Z
11
+ date: 2015-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
111
  version: '0'
112
112
  requirements: []
113
113
  rubyforge_project:
114
- rubygems_version: 2.2.0
114
+ rubygems_version: 2.4.5.1
115
115
  signing_key:
116
116
  specification_version: 4
117
117
  summary: Small library of classes for common SMS-related functionality.