mms2r 1.0.0

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.
Files changed (55) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +54 -0
  3. data/README.txt +81 -0
  4. data/Rakefile +30 -0
  5. data/conf/mms2r_cingularmedia_transform.yml +6 -0
  6. data/conf/mms2r_sprintmedia_ignore.yml +10 -0
  7. data/conf/mms2r_tmobilemedia_ignore.yml +17 -0
  8. data/conf/mms2r_verizonmedia_ignore.yml +3 -0
  9. data/lib/mms2r.rb +3 -0
  10. data/lib/mms2r/cingular_media.rb +11 -0
  11. data/lib/mms2r/media.rb +345 -0
  12. data/lib/mms2r/mmode_media.rb +13 -0
  13. data/lib/mms2r/sprint_media.rb +50 -0
  14. data/lib/mms2r/tmobile_media.rb +11 -0
  15. data/lib/mms2r/verizon_media.rb +11 -0
  16. data/lib/mms2r/version.rb +12 -0
  17. data/lib/vendor/text/format.rb +1466 -0
  18. data/lib/vendor/tmail.rb +3 -0
  19. data/lib/vendor/tmail/address.rb +242 -0
  20. data/lib/vendor/tmail/attachments.rb +39 -0
  21. data/lib/vendor/tmail/base64.rb +71 -0
  22. data/lib/vendor/tmail/config.rb +69 -0
  23. data/lib/vendor/tmail/encode.rb +467 -0
  24. data/lib/vendor/tmail/facade.rb +552 -0
  25. data/lib/vendor/tmail/header.rb +914 -0
  26. data/lib/vendor/tmail/info.rb +35 -0
  27. data/lib/vendor/tmail/loader.rb +1 -0
  28. data/lib/vendor/tmail/mail.rb +447 -0
  29. data/lib/vendor/tmail/mailbox.rb +433 -0
  30. data/lib/vendor/tmail/mbox.rb +1 -0
  31. data/lib/vendor/tmail/net.rb +280 -0
  32. data/lib/vendor/tmail/obsolete.rb +135 -0
  33. data/lib/vendor/tmail/parser.rb +1522 -0
  34. data/lib/vendor/tmail/port.rb +377 -0
  35. data/lib/vendor/tmail/quoting.rb +131 -0
  36. data/lib/vendor/tmail/scanner.rb +41 -0
  37. data/lib/vendor/tmail/scanner_r.rb +263 -0
  38. data/lib/vendor/tmail/stringio.rb +277 -0
  39. data/lib/vendor/tmail/tmail.rb +1 -0
  40. data/lib/vendor/tmail/utils.rb +238 -0
  41. data/test/files/dot.jpg +0 -0
  42. data/test/files/sprint-image-01.mail +195 -0
  43. data/test/files/sprint-text-01.mail +8 -0
  44. data/test/files/sprint-video-01.mail +195 -0
  45. data/test/files/sprint.mov +0 -0
  46. data/test/files/verizon-image-01.mail +815 -0
  47. data/test/files/verizon-text-01.mail +11 -0
  48. data/test/files/verizon-video-01.mail +336 -0
  49. data/test/test_mms2r_cingular.rb +52 -0
  50. data/test/test_mms2r_media.rb +311 -0
  51. data/test/test_mms2r_mmode.rb +52 -0
  52. data/test/test_mms2r_sprint.rb +154 -0
  53. data/test/test_mms2r_tmobile.rb +169 -0
  54. data/test/test_mms2r_verizon.rb +74 -0
  55. metadata +130 -0
@@ -0,0 +1,41 @@
1
+ #
2
+ # scanner.rb
3
+ #
4
+ #--
5
+ # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining
8
+ # a copy of this software and associated documentation files (the
9
+ # "Software"), to deal in the Software without restriction, including
10
+ # without limitation the rights to use, copy, modify, merge, publish,
11
+ # distribute, sublicense, and/or sell copies of the Software, and to
12
+ # permit persons to whom the Software is furnished to do so, subject to
13
+ # the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be
16
+ # included in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ #
26
+ # Note: Originally licensed under LGPL v2+. Using MIT license for Rails
27
+ # with permission of Minero Aoki.
28
+ #++
29
+
30
+ require 'tmail/utils'
31
+
32
+ module TMail
33
+ require 'tmail/scanner_r.rb'
34
+ begin
35
+ raise LoadError, 'Turn off Ruby extention by user choice' if ENV['NORUBYEXT']
36
+ require 'tmail/scanner_c.so'
37
+ Scanner = Scanner_C
38
+ rescue LoadError
39
+ Scanner = Scanner_R
40
+ end
41
+ end
@@ -0,0 +1,263 @@
1
+ #
2
+ # scanner_r.rb
3
+ #
4
+ #--
5
+ # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining
8
+ # a copy of this software and associated documentation files (the
9
+ # "Software"), to deal in the Software without restriction, including
10
+ # without limitation the rights to use, copy, modify, merge, publish,
11
+ # distribute, sublicense, and/or sell copies of the Software, and to
12
+ # permit persons to whom the Software is furnished to do so, subject to
13
+ # the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be
16
+ # included in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ #
26
+ # Note: Originally licensed under LGPL v2+. Using MIT license for Rails
27
+ # with permission of Minero Aoki.
28
+ #++
29
+
30
+ require 'tmail/config'
31
+
32
+
33
+ module TMail
34
+
35
+ class Scanner_R
36
+
37
+ Version = '0.10.7'
38
+ Version.freeze
39
+
40
+ MIME_HEADERS = {
41
+ :CTYPE => true,
42
+ :CENCODING => true,
43
+ :CDISPOSITION => true
44
+ }
45
+
46
+ alnum = 'a-zA-Z0-9'
47
+ atomsyms = %q[ _#!$%&`'*+-{|}~^@/=? ].strip
48
+ tokensyms = %q[ _#!$%&`'*+-{|}~^@. ].strip
49
+
50
+ atomchars = alnum + Regexp.quote(atomsyms)
51
+ tokenchars = alnum + Regexp.quote(tokensyms)
52
+ iso2022str = '\e(?!\(B)..(?:[^\e]+|\e(?!\(B)..)*\e\(B'
53
+
54
+ eucstr = '(?:[\xa1-\xfe][\xa1-\xfe])+'
55
+ sjisstr = '(?:[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc])+'
56
+ utf8str = '(?:[\xc0-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf][\x80-\xbf])+'
57
+
58
+ quoted_with_iso2022 = /\A(?:[^\\\e"]+|#{iso2022str})+/n
59
+ domlit_with_iso2022 = /\A(?:[^\\\e\]]+|#{iso2022str})+/n
60
+ comment_with_iso2022 = /\A(?:[^\\\e()]+|#{iso2022str})+/n
61
+
62
+ quoted_without_iso2022 = /\A[^\\"]+/n
63
+ domlit_without_iso2022 = /\A[^\\\]]+/n
64
+ comment_without_iso2022 = /\A[^\\()]+/n
65
+
66
+ PATTERN_TABLE = {}
67
+ PATTERN_TABLE['EUC'] =
68
+ [
69
+ /\A(?:[#{atomchars}]+|#{iso2022str}|#{eucstr})+/n,
70
+ /\A(?:[#{tokenchars}]+|#{iso2022str}|#{eucstr})+/n,
71
+ quoted_with_iso2022,
72
+ domlit_with_iso2022,
73
+ comment_with_iso2022
74
+ ]
75
+ PATTERN_TABLE['SJIS'] =
76
+ [
77
+ /\A(?:[#{atomchars}]+|#{iso2022str}|#{sjisstr})+/n,
78
+ /\A(?:[#{tokenchars}]+|#{iso2022str}|#{sjisstr})+/n,
79
+ quoted_with_iso2022,
80
+ domlit_with_iso2022,
81
+ comment_with_iso2022
82
+ ]
83
+ PATTERN_TABLE['UTF8'] =
84
+ [
85
+ /\A(?:[#{atomchars}]+|#{utf8str})+/n,
86
+ /\A(?:[#{tokenchars}]+|#{utf8str})+/n,
87
+ quoted_without_iso2022,
88
+ domlit_without_iso2022,
89
+ comment_without_iso2022
90
+ ]
91
+ PATTERN_TABLE['NONE'] =
92
+ [
93
+ /\A[#{atomchars}]+/n,
94
+ /\A[#{tokenchars}]+/n,
95
+ quoted_without_iso2022,
96
+ domlit_without_iso2022,
97
+ comment_without_iso2022
98
+ ]
99
+
100
+
101
+ def initialize( str, scantype, comments )
102
+ init_scanner str
103
+ @comments = comments || []
104
+ @debug = false
105
+
106
+ # fix scanner mode
107
+ @received = (scantype == :RECEIVED)
108
+ @is_mime_header = MIME_HEADERS[scantype]
109
+
110
+ atom, token, @quoted_re, @domlit_re, @comment_re = PATTERN_TABLE[$KCODE]
111
+ @word_re = (MIME_HEADERS[scantype] ? token : atom)
112
+ end
113
+
114
+ attr_accessor :debug
115
+
116
+ def scan( &block )
117
+ if @debug
118
+ scan_main do |arr|
119
+ s, v = arr
120
+ printf "%7d %-10s %s\n",
121
+ rest_size(),
122
+ s.respond_to?(:id2name) ? s.id2name : s.inspect,
123
+ v.inspect
124
+ yield arr
125
+ end
126
+ else
127
+ scan_main(&block)
128
+ end
129
+ end
130
+
131
+ private
132
+
133
+ RECV_TOKEN = {
134
+ 'from' => :FROM,
135
+ 'by' => :BY,
136
+ 'via' => :VIA,
137
+ 'with' => :WITH,
138
+ 'id' => :ID,
139
+ 'for' => :FOR
140
+ }
141
+
142
+ def scan_main
143
+ until eof?
144
+ if skip(/\A[\n\r\t ]+/n) # LWSP
145
+ break if eof?
146
+ end
147
+
148
+ if s = readstr(@word_re)
149
+ if @is_mime_header
150
+ yield :TOKEN, s
151
+ else
152
+ # atom
153
+ if /\A\d+\z/ === s
154
+ yield :DIGIT, s
155
+ elsif @received
156
+ yield RECV_TOKEN[s.downcase] || :ATOM, s
157
+ else
158
+ yield :ATOM, s
159
+ end
160
+ end
161
+
162
+ elsif skip(/\A"/)
163
+ yield :QUOTED, scan_quoted_word()
164
+
165
+ elsif skip(/\A\[/)
166
+ yield :DOMLIT, scan_domain_literal()
167
+
168
+ elsif skip(/\A\(/)
169
+ @comments.push scan_comment()
170
+
171
+ else
172
+ c = readchar()
173
+ yield c, c
174
+ end
175
+ end
176
+
177
+ yield false, '$'
178
+ end
179
+
180
+ def scan_quoted_word
181
+ scan_qstr(@quoted_re, /\A"/, 'quoted-word')
182
+ end
183
+
184
+ def scan_domain_literal
185
+ '[' + scan_qstr(@domlit_re, /\A\]/, 'domain-literal') + ']'
186
+ end
187
+
188
+ def scan_qstr( pattern, terminal, type )
189
+ result = ''
190
+ until eof?
191
+ if s = readstr(pattern) then result << s
192
+ elsif skip(terminal) then return result
193
+ elsif skip(/\A\\/) then result << readchar()
194
+ else
195
+ raise "TMail FATAL: not match in #{type}"
196
+ end
197
+ end
198
+ scan_error! "found unterminated #{type}"
199
+ end
200
+
201
+ def scan_comment
202
+ result = ''
203
+ nest = 1
204
+ content = @comment_re
205
+
206
+ until eof?
207
+ if s = readstr(content) then result << s
208
+ elsif skip(/\A\)/) then nest -= 1
209
+ return result if nest == 0
210
+ result << ')'
211
+ elsif skip(/\A\(/) then nest += 1
212
+ result << '('
213
+ elsif skip(/\A\\/) then result << readchar()
214
+ else
215
+ raise 'TMail FATAL: not match in comment'
216
+ end
217
+ end
218
+ scan_error! 'found unterminated comment'
219
+ end
220
+
221
+ # string scanner
222
+
223
+ def init_scanner( str )
224
+ @src = str
225
+ end
226
+
227
+ def eof?
228
+ @src.empty?
229
+ end
230
+
231
+ def rest_size
232
+ @src.size
233
+ end
234
+
235
+ def readstr( re )
236
+ if m = re.match(@src)
237
+ @src = m.post_match
238
+ m[0]
239
+ else
240
+ nil
241
+ end
242
+ end
243
+
244
+ def readchar
245
+ readstr(/\A./)
246
+ end
247
+
248
+ def skip( re )
249
+ if m = re.match(@src)
250
+ @src = m.post_match
251
+ true
252
+ else
253
+ false
254
+ end
255
+ end
256
+
257
+ def scan_error!( msg )
258
+ raise SyntaxError, msg
259
+ end
260
+
261
+ end
262
+
263
+ end # module TMail
@@ -0,0 +1,277 @@
1
+ #
2
+ # stringio.rb
3
+ #
4
+ #--
5
+ # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining
8
+ # a copy of this software and associated documentation files (the
9
+ # "Software"), to deal in the Software without restriction, including
10
+ # without limitation the rights to use, copy, modify, merge, publish,
11
+ # distribute, sublicense, and/or sell copies of the Software, and to
12
+ # permit persons to whom the Software is furnished to do so, subject to
13
+ # the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be
16
+ # included in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ #
26
+ # Note: Originally licensed under LGPL v2+. Using MIT license for Rails
27
+ # with permission of Minero Aoki.
28
+ #++
29
+
30
+ class StringInput#:nodoc:
31
+
32
+ include Enumerable
33
+
34
+ class << self
35
+
36
+ def new( str )
37
+ if block_given?
38
+ begin
39
+ f = super
40
+ yield f
41
+ ensure
42
+ f.close if f
43
+ end
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ alias open new
50
+
51
+ end
52
+
53
+ def initialize( str )
54
+ @src = str
55
+ @pos = 0
56
+ @closed = false
57
+ @lineno = 0
58
+ end
59
+
60
+ attr_reader :lineno
61
+
62
+ def string
63
+ @src
64
+ end
65
+
66
+ def inspect
67
+ "#<#{self.class}:#{@closed ? 'closed' : 'open'},src=#{@src[0,30].inspect}>"
68
+ end
69
+
70
+ def close
71
+ stream_check!
72
+ @pos = nil
73
+ @closed = true
74
+ end
75
+
76
+ def closed?
77
+ @closed
78
+ end
79
+
80
+ def pos
81
+ stream_check!
82
+ [@pos, @src.size].min
83
+ end
84
+
85
+ alias tell pos
86
+
87
+ def seek( offset, whence = IO::SEEK_SET )
88
+ stream_check!
89
+ case whence
90
+ when IO::SEEK_SET
91
+ @pos = offset
92
+ when IO::SEEK_CUR
93
+ @pos += offset
94
+ when IO::SEEK_END
95
+ @pos = @src.size - offset
96
+ else
97
+ raise ArgumentError, "unknown seek flag: #{whence}"
98
+ end
99
+ @pos = 0 if @pos < 0
100
+ @pos = [@pos, @src.size + 1].min
101
+ offset
102
+ end
103
+
104
+ def rewind
105
+ stream_check!
106
+ @pos = 0
107
+ end
108
+
109
+ def eof?
110
+ stream_check!
111
+ @pos > @src.size
112
+ end
113
+
114
+ def each( &block )
115
+ stream_check!
116
+ begin
117
+ @src.each(&block)
118
+ ensure
119
+ @pos = 0
120
+ end
121
+ end
122
+
123
+ def gets
124
+ stream_check!
125
+ if idx = @src.index(?\n, @pos)
126
+ idx += 1 # "\n".size
127
+ line = @src[ @pos ... idx ]
128
+ @pos = idx
129
+ @pos += 1 if @pos == @src.size
130
+ else
131
+ line = @src[ @pos .. -1 ]
132
+ @pos = @src.size + 1
133
+ end
134
+ @lineno += 1
135
+
136
+ line
137
+ end
138
+
139
+ def getc
140
+ stream_check!
141
+ ch = @src[@pos]
142
+ @pos += 1
143
+ @pos += 1 if @pos == @src.size
144
+ ch
145
+ end
146
+
147
+ def read( len = nil )
148
+ stream_check!
149
+ return read_all unless len
150
+ str = @src[@pos, len]
151
+ @pos += len
152
+ @pos += 1 if @pos == @src.size
153
+ str
154
+ end
155
+
156
+ alias sysread read
157
+
158
+ def read_all
159
+ stream_check!
160
+ return nil if eof?
161
+ rest = @src[@pos ... @src.size]
162
+ @pos = @src.size + 1
163
+ rest
164
+ end
165
+
166
+ def stream_check!
167
+ @closed and raise IOError, 'closed stream'
168
+ end
169
+
170
+ end
171
+
172
+
173
+ class StringOutput#:nodoc:
174
+
175
+ class << self
176
+
177
+ def new( str = '' )
178
+ if block_given?
179
+ begin
180
+ f = super
181
+ yield f
182
+ ensure
183
+ f.close if f
184
+ end
185
+ else
186
+ super
187
+ end
188
+ end
189
+
190
+ alias open new
191
+
192
+ end
193
+
194
+ def initialize( str = '' )
195
+ @dest = str
196
+ @closed = false
197
+ end
198
+
199
+ def close
200
+ @closed = true
201
+ end
202
+
203
+ def closed?
204
+ @closed
205
+ end
206
+
207
+ def string
208
+ @dest
209
+ end
210
+
211
+ alias value string
212
+ alias to_str string
213
+
214
+ def size
215
+ @dest.size
216
+ end
217
+
218
+ alias pos size
219
+
220
+ def inspect
221
+ "#<#{self.class}:#{@dest ? 'open' : 'closed'},#{id}>"
222
+ end
223
+
224
+ def print( *args )
225
+ stream_check!
226
+ raise ArgumentError, 'wrong # of argument (0 for >1)' if args.empty?
227
+ args.each do |s|
228
+ raise ArgumentError, 'nil not allowed' if s.nil?
229
+ @dest << s.to_s
230
+ end
231
+ nil
232
+ end
233
+
234
+ def puts( *args )
235
+ stream_check!
236
+ args.each do |str|
237
+ @dest << (s = str.to_s)
238
+ @dest << "\n" unless s[-1] == ?\n
239
+ end
240
+ @dest << "\n" if args.empty?
241
+ nil
242
+ end
243
+
244
+ def putc( ch )
245
+ stream_check!
246
+ @dest << ch.chr
247
+ nil
248
+ end
249
+
250
+ def printf( *args )
251
+ stream_check!
252
+ @dest << sprintf(*args)
253
+ nil
254
+ end
255
+
256
+ def write( str )
257
+ stream_check!
258
+ s = str.to_s
259
+ @dest << s
260
+ s.size
261
+ end
262
+
263
+ alias syswrite write
264
+
265
+ def <<( str )
266
+ stream_check!
267
+ @dest << str.to_s
268
+ self
269
+ end
270
+
271
+ private
272
+
273
+ def stream_check!
274
+ @closed and raise IOError, 'closed stream'
275
+ end
276
+
277
+ end