Project

General

Profile

« Previous | Next » 

Revision 9630

Use Mail instead of TMail in MailHandler.

View differences:

trunk/app/models/attachment.rb
101 101
      logger.info("Saving attachment '#{self.diskfile}' (#{@temp_file.size} bytes)")
102 102
      md5 = Digest::MD5.new
103 103
      File.open(diskfile, "wb") do |f|
104
        buffer = ""
105
        while (buffer = @temp_file.read(8192))
106
          f.write(buffer)
107
          md5.update(buffer)
104
        if @temp_file.respond_to?(:read)
105
          buffer = ""
106
          while (buffer = @temp_file.read(8192))
107
            f.write(buffer)
108
            md5.update(buffer)
109
          end
110
        else
111
          f.write(@temp_file)
112
          md5.update(@temp_file)
108 113
        end
109 114
      end
110 115
      self.digest = md5.hexdigest
trunk/app/models/mail_handler.rb
15 15
# along with this program; if not, write to the Free Software
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18
require 'vendor/tmail'
19

  
20
class MailHandler
18
class MailHandler < ActionMailer::Base
21 19
  include ActionView::Helpers::SanitizeHelper
22 20
  include Redmine::I18n
23 21

  
......
42 40

  
43 41
    @@handler_options[:no_permission_check] = (@@handler_options[:no_permission_check].to_s == '1' ? true : false)
44 42

  
45
    mail = TMail::Mail.parse(email)
46
    mail.base64_decode
47
    new.receive(mail)
43
    email.force_encoding('ASCII-8BIT') if email.respond_to?(:force_encoding)
44
    super(email)
48 45
  end
49 46

  
50 47
  def logger
......
71 68
    end
72 69
    # Ignore auto generated emails
73 70
    self.class.ignored_emails_headers.each do |key, ignored_value|
74
      value = email.header_string(key)
71
      value = email.header[key]
75 72
      if value && value.to_s.downcase == ignored_value.downcase
76 73
        if logger && logger.info
77 74
          logger.info "MailHandler: ignoring email with #{key}:#{value} header"
......
118 115

  
119 116
  private
120 117

  
121
  MESSAGE_ID_RE = %r{^<redmine\.([a-z0-9_]+)\-(\d+)\.\d+@}
118
  MESSAGE_ID_RE = %r{^<?redmine\.([a-z0-9_]+)\-(\d+)\.\d+@}
122 119
  ISSUE_REPLY_SUBJECT_RE = %r{\[[^\]]*#(\d+)\]}
123 120
  MESSAGE_REPLY_SUBJECT_RE = %r{\[[^\]]*msg(\d+)\]}
124 121

  
......
245 242
    if email.attachments && email.attachments.any?
246 243
      email.attachments.each do |attachment|
247 244
        obj.attachments << Attachment.create(:container => obj,
248
                          :file => attachment,
245
                          :file => attachment.decoded,
246
                          :filename => attachment.filename,
249 247
                          :author => user,
250
                          :content_type => attachment.content_type)
248
                          :content_type => attachment.mime_type)
251 249
      end
252 250
    end
253 251
  end
......
295 293
    keys.reject! {|k| k.blank?}
296 294
    keys.collect! {|k| Regexp.escape(k)}
297 295
    format ||= '.+'
298
    text.gsub!(/^(#{keys.join('|')})[ \t]*:[ \t]*(#{format})\s*$/i, '')
299
    $2 && $2.strip
296
    keyword = nil
297
    regexp = /^(#{keys.join('|')})[ \t]*:[ \t]*(#{format})\s*$/i
298
    if m = text.match(regexp)
299
      keyword = m[2].strip
300
      text.gsub!(regexp, '')
301
    end
302
    keyword
300 303
  end
301 304

  
302 305
  def target_project
......
347 350
  # If not found (eg. HTML-only email), returns the body with tags removed
348 351
  def plain_text_body
349 352
    return @plain_text_body unless @plain_text_body.nil?
350
    parts = @email.parts.collect {|c| (c.respond_to?(:parts) && !c.parts.empty?) ? c.parts : c}.flatten
351
    if parts.empty?
352
      parts << @email
353

  
354
    part = email.text_part || email.html_part || email
355
    @plain_text_body = Redmine::CodesetUtil.to_utf8(part.body.decoded, part.charset)
356

  
357
    if @plain_text_body.respond_to?(:force_encoding)
358
     # @plain_text_body = @plain_text_body.force_encoding(@email.charset).encode("UTF-8")
353 359
    end
354
    plain_text_part = parts.detect {|p| p.content_type == 'text/plain'}
355
    if plain_text_part.nil?
356
      # no text/plain part found, assuming html-only email
357
      # strip html tags and remove doctype directive
358
      @plain_text_body = strip_tags(@email.body.to_s)
359
      @plain_text_body.gsub! %r{^<!DOCTYPE .*$}, ''
360
    else
361
      @plain_text_body = plain_text_part.body.to_s
362
    end
363
    @plain_text_body.strip!
360

  
361
    # strip html tags and remove doctype directive
362
    @plain_text_body = strip_tags(@plain_text_body.strip)
363
    @plain_text_body.sub! %r{^<!DOCTYPE .*$}, ''
364 364
    @plain_text_body
365 365
  end
366 366

  
......
407 407
  # Creates a User for the +email+ sender
408 408
  # Returns the user or nil if it could not be created
409 409
  def create_user_from_email
410
    addr = email.from_addrs.to_a.first
411
    if addr && !addr.spec.blank?
412
      user = self.class.new_user_from_attributes(addr.spec, TMail::Unquoter.unquote_and_convert_to(addr.name, 'utf-8'))
410
    from = email.header['from'].to_s
411
    addr, name = from, nil
412
    if m = from.match(/^"?(.+?)"?\s+<(.+@.+)>$/)
413
      addr, name = m[2], m[1]
414
    end
415
    if addr.present?
416
      user = self.class.new_user_from_attributes(addr, name)
413 417
      if user.save
414 418
        user
415 419
      else
trunk/lib/vendor/tmail.rb
1
$:.unshift "#{File.dirname(__FILE__)}/tmail-1.2.7"
2

  
3
require 'tmail'
4

  
5
module TMail
6
  # TMail::Unquoter.convert_to_with_fallback_on_iso_8859_1 introduced in TMail 1.2.7
7
  # triggers a test failure in test_add_issue_with_japanese_keywords(MailHandlerTest)
8
  class Unquoter
9
    class << self
10
      alias_method :convert_to, :convert_to_without_fallback_on_iso_8859_1
11
    end
12
  end
13

  
14
  # Patch for TMail 1.2.7. See http://www.redmine.org/issues/8751
15
  class Encoder
16
    def puts_meta(str)
17
      add_text str
18
    end
19
  end
20
end
trunk/lib/vendor/tmail-1.2.7/tmail.rb
1
require 'tmail/version'
2
require 'tmail/mail'
3
require 'tmail/mailbox'
4
require 'tmail/core_extensions'
5
require 'tmail/net'
6
require 'tmail/vendor/rchardet-1.3/lib/rchardet'
trunk/lib/vendor/tmail-1.2.7/tmail/parser.rb
1
#
2
# DO NOT MODIFY!!!!
3
# This file is automatically generated by racc 1.4.5
4
# from racc grammer file "lib/tmail/parser.y".
5
#
6

  
7
require 'racc/parser'
8

  
9

  
10
#
11
# parser.rb
12
#
13
# Copyright (c) 1998-2007 Minero Aoki
14
#
15
# This program is free software.
16
# You can distribute/modify this program under the terms of
17
# the GNU Lesser General Public License version 2.1.
18
#
19

  
20
require 'tmail/scanner'
21
require 'tmail/utils'
22

  
23

  
24
module TMail
25

  
26
  class Parser < Racc::Parser
27

  
28
module_eval <<'..end lib/tmail/parser.y modeval..id2dd1c7d21d', 'lib/tmail/parser.y', 340
29

  
30
  include TextUtils
31

  
32
  def self.parse( ident, str, cmt = nil )
33
    str = special_quote_address(str) if ident.to_s =~ /M?ADDRESS/
34
    new.parse(ident, str, cmt)
35
  end
36

  
37
  def self.special_quote_address(str) #:nodoc:
38
    # Takes a string which is an address and adds quotation marks to special
39
    # edge case methods that the RACC parser can not handle.
40
    #
41
    # Right now just handles two edge cases:
42
    #
43
    # Full stop as the last character of the display name:
44
    #   Mikel L. <[email protected]>
45
    # Returns:
46
    #   "Mikel L." <[email protected]>
47
    #
48
    # Unquoted @ symbol in the display name:
49
    #   [email protected] <[email protected]>
50
    # Returns:
51
    #   "[email protected]" <[email protected]>
52
    #
53
    # Any other address not matching these patterns just gets returned as is.
54
    case
55
    # This handles the missing "" in an older version of Apple Mail.app
56
    # around the display name when the display name contains a '@'
57
    # like '[email protected] <[email protected]>'
58
    # Just quotes it to: '"[email protected]" <[email protected]>'
59
    when str =~ /\A([^"].+@.+[^"])\s(<.*?>)\Z/
60
      return "\"#{$1}\" #{$2}"
61
    # This handles cases where 'Mikel A. <[email protected]>' which is a trailing
62
    # full stop before the address section.  Just quotes it to
63
    # '"Mikel A." <[email protected]>'
64
    when str =~ /\A(.*?\.)\s(<.*?>)\s*\Z/
65
      return "\"#{$1}\" #{$2}"
66
    else
67
      str
68
    end
69
  end
70

  
71
  MAILP_DEBUG = false
72

  
73
  def initialize
74
    self.debug = MAILP_DEBUG
75
  end
76

  
77
  def debug=( flag )
78
    @yydebug = flag && Racc_debug_parser
79
    @scanner_debug = flag
80
  end
81

  
82
  def debug
83
    @yydebug
84
  end
85

  
86
  def parse( ident, str, comments = nil )
87
    @scanner = Scanner.new(str, ident, comments)
88
    @scanner.debug = @scanner_debug
89
    @first = [ident, ident]
90
    result = yyparse(self, :parse_in)
91
    comments.map! {|c| to_kcode(c) } if comments
92
    result
93
  end
94

  
95
  private
96

  
97
  def parse_in( &block )
98
    yield @first
99
    @scanner.scan(&block)
100
  end
101
  
102
  def on_error( t, val, vstack )
103
    raise TMail::SyntaxError, "parse error on token #{racc_token2str t}"
104
  end
105

  
106
..end lib/tmail/parser.y modeval..id2dd1c7d21d
107

  
108
##### racc 1.4.5 generates ###
109

  
110
racc_reduce_table = [
111
 0, 0, :racc_error,
112
 2, 35, :_reduce_1,
113
 2, 35, :_reduce_2,
114
 2, 35, :_reduce_3,
115
 2, 35, :_reduce_4,
116
 2, 35, :_reduce_5,
117
 2, 35, :_reduce_6,
118
 2, 35, :_reduce_7,
119
 2, 35, :_reduce_8,
120
 2, 35, :_reduce_9,
121
 2, 35, :_reduce_10,
122
 2, 35, :_reduce_11,
123
 2, 35, :_reduce_12,
124
 6, 36, :_reduce_13,
125
 0, 48, :_reduce_none,
126
 2, 48, :_reduce_none,
127
 3, 49, :_reduce_16,
128
 5, 49, :_reduce_17,
129
 1, 50, :_reduce_18,
130
 7, 37, :_reduce_19,
131
 0, 51, :_reduce_none,
132
 2, 51, :_reduce_21,
133
 0, 52, :_reduce_none,
134
 2, 52, :_reduce_23,
135
 1, 58, :_reduce_24,
136
 3, 58, :_reduce_25,
137
 2, 58, :_reduce_26,
138
 0, 53, :_reduce_none,
139
 2, 53, :_reduce_28,
140
 0, 54, :_reduce_29,
141
 3, 54, :_reduce_30,
142
 0, 55, :_reduce_none,
143
 2, 55, :_reduce_32,
144
 2, 55, :_reduce_33,
145
 0, 56, :_reduce_none,
146
 2, 56, :_reduce_35,
147
 1, 61, :_reduce_36,
148
 1, 61, :_reduce_37,
149
 0, 57, :_reduce_none,
150
 2, 57, :_reduce_39,
151
 1, 38, :_reduce_none,
152
 1, 38, :_reduce_none,
153
 3, 38, :_reduce_none,
154
 1, 46, :_reduce_none,
155
 1, 46, :_reduce_none,
156
 1, 46, :_reduce_none,
157
 1, 39, :_reduce_none,
158
 2, 39, :_reduce_47,
159
 1, 64, :_reduce_48,
160
 3, 64, :_reduce_49,
161
 1, 68, :_reduce_none,
162
 1, 68, :_reduce_none,
163
 1, 69, :_reduce_52,
164
 3, 69, :_reduce_53,
165
 1, 47, :_reduce_none,
166
 1, 47, :_reduce_none,
167
 2, 47, :_reduce_56,
168
 2, 67, :_reduce_none,
169
 3, 65, :_reduce_58,
170
 2, 65, :_reduce_59,
171
 1, 70, :_reduce_60,
172
 2, 70, :_reduce_61,
173
 4, 62, :_reduce_62,
174
 3, 62, :_reduce_63,
175
 2, 72, :_reduce_none,
176
 2, 73, :_reduce_65,
177
 4, 73, :_reduce_66,
178
 3, 63, :_reduce_67,
179
 1, 63, :_reduce_68,
180
 1, 74, :_reduce_none,
181
 2, 74, :_reduce_70,
182
 1, 71, :_reduce_71,
183
 3, 71, :_reduce_72,
184
 1, 59, :_reduce_73,
185
 3, 59, :_reduce_74,
186
 1, 76, :_reduce_75,
187
 2, 76, :_reduce_76,
188
 1, 75, :_reduce_none,
189
 1, 75, :_reduce_none,
190
 1, 75, :_reduce_none,
191
 1, 77, :_reduce_none,
192
 1, 77, :_reduce_none,
193
 1, 77, :_reduce_none,
194
 1, 66, :_reduce_none,
195
 2, 66, :_reduce_none,
196
 3, 60, :_reduce_85,
197
 1, 40, :_reduce_86,
198
 3, 40, :_reduce_87,
199
 1, 79, :_reduce_none,
200
 2, 79, :_reduce_89,
201
 1, 41, :_reduce_90,
202
 2, 41, :_reduce_91,
203
 3, 42, :_reduce_92,
204
 5, 43, :_reduce_93,
205
 3, 43, :_reduce_94,
206
 0, 80, :_reduce_95,
207
 5, 80, :_reduce_96,
208
 5, 80, :_reduce_97,
209
 1, 44, :_reduce_98,
210
 3, 45, :_reduce_99,
211
 0, 81, :_reduce_none,
212
 1, 81, :_reduce_none,
213
 1, 78, :_reduce_none,
214
 1, 78, :_reduce_none,
215
 1, 78, :_reduce_none,
216
 1, 78, :_reduce_none,
217
 1, 78, :_reduce_none,
218
 1, 78, :_reduce_none,
219
 1, 78, :_reduce_none ]
220

  
221
racc_reduce_n = 109
222

  
223
racc_shift_n = 167
224

  
225
racc_action_table = [
226
   -69,   130,   -70,    23,    25,   153,    94,    29,    31,   142,
227
   143,    16,    17,    20,    22,    98,   -69,   154,   -70,    32,
228
   -69,   107,   -70,   145,   146,    78,   -69,    91,   -70,    75,
229
   -70,    23,    25,   120,    88,    29,    31,   105,   106,    16,
230
    17,    20,    22,    81,    27,    23,    25,    32,   112,    29,
231
    31,    96,    80,    16,    17,    20,    22,   117,    27,    23,
232
    25,    32,    79,    29,    31,    78,   123,    16,    17,    20,
233
    22,   100,    27,    23,    25,    32,   125,    29,    31,   113,
234
   115,    16,    17,    20,    22,   126,    23,    25,   101,    32,
235
    29,    31,    91,   128,    16,    17,    20,    22,   129,    27,
236
    23,    25,    32,   101,    29,    31,   101,    75,    16,    17,
237
    20,    22,    77,    52,    23,    25,    32,    65,    29,    31,
238
   133,    78,    16,    17,    20,    22,    62,    23,    25,   136,
239
    32,    29,    31,    60,    44,    16,    17,    20,    22,   139,
240
    23,    25,   101,    32,    29,    31,   101,   100,    16,    17,
241
    20,    22,   100,    27,    23,    25,    32,   101,    29,    31,
242
   147,   148,    16,    17,    20,    22,   151,    23,    25,   152,
243
    32,    29,    31,    74,    42,    16,    17,    20,    22,   156,
244
   158,    92,    40,    32,    23,    25,    15,    68,    29,    31,
245
   163,    40,    16,    17,    20,    22,   165,    27,    23,    25,
246
    32,   166,    29,    31,   nil,   nil,    16,    17,    20,    22,
247
   nil,    27,    23,    25,    32,   nil,    29,    31,   nil,   nil,
248
    16,    17,    20,    22,   nil,    23,    25,   nil,    32,    29,
249
    31,   nil,   nil,    16,    17,    20,    22,   nil,    23,    25,
250
   nil,    32,    29,    31,   nil,   nil,    16,    17,    20,    22,
251
   nil,    23,    25,   nil,    32,    29,    31,   nil,   nil,    16,
252
    17,    20,    22,   nil,    27,   nil,   nil,    32,    23,    25,
253
   120,   nil,    29,    31,   nil,   nil,    16,    17,    20,    22,
254
   nil,    27,    23,    25,    32,   nil,    29,    31,   nil,   nil,
255
    16,    17,    20,    22,   nil,    23,    25,   109,    32,    29,
256
    31,    74,   nil,    16,    17,    20,    22,   nil,    84,    25,
257
   nil,    32,    29,    31,   nil,    87,    16,    17,    20,    22,
258
    84,    25,   nil,   109,    29,    31,   nil,    87,    16,    17,
259
    20,    22,    84,    25,   nil,   nil,    29,    31,   nil,    87,
260
    16,    17,    20,    22,    84,    25,   nil,   nil,    29,    31,
261
   nil,    87,    16,    17,    20,    22,    84,    25,   nil,   nil,
262
    29,    31,   nil,    87,    16,    17,    20,    22,    84,    25,
263
   nil,   nil,    29,    31,   nil,    87,    16,    17,    20,    22,
264
     4,     6,     7,     8,     9,    10,    11,    12,    13,     1,
265
     2,     3,    84,    25,   nil,   nil,    29,    31,   nil,    87,
266
    16,    17,    20,    22 ]
267

  
268
racc_action_check = [
269
    28,   112,    75,    71,    71,   143,    56,    71,    71,   134,
270
   134,    71,    71,    71,    71,    62,    28,   143,    75,    71,
271
    28,    73,    75,   136,   136,    51,    28,    50,    75,    28,
272
    75,   127,   127,   127,    45,   127,   127,    72,    72,   127,
273
   127,   127,   127,    42,   127,     3,     3,   127,    80,     3,
274
     3,    60,    41,     3,     3,     3,     3,    89,     3,   151,
275
   151,     3,    40,   151,   151,    36,    96,   151,   151,   151,
276
   151,    97,   151,    55,    55,   151,    98,    55,    55,    86,
277
    86,    55,    55,    55,    55,   100,     7,     7,    86,    55,
278
     7,     7,   102,   104,     7,     7,     7,     7,   105,     7,
279
     8,     8,     7,   108,     8,     8,   111,    70,     8,     8,
280
     8,     8,    33,     8,     9,     9,     8,    13,     9,     9,
281
   117,   121,     9,     9,     9,     9,    12,    10,    10,   126,
282
     9,    10,    10,    11,     6,    10,    10,    10,    10,   130,
283
     2,     2,   131,    10,     2,     2,    67,   135,     2,     2,
284
     2,     2,    66,     2,   122,   122,     2,   138,   122,   122,
285
   139,   140,   122,   122,   122,   122,   141,    52,    52,   142,
286
   122,    52,    52,    52,     5,    52,    52,    52,    52,   147,
287
   150,    52,     4,    52,    26,    26,     1,    26,    26,    26,
288
   156,   158,    26,    26,    26,    26,   162,    26,    68,    68,
289
    26,   163,    68,    68,   nil,   nil,    68,    68,    68,    68,
290
   nil,    68,    59,    59,    68,   nil,    59,    59,   nil,   nil,
291
    59,    59,    59,    59,   nil,   154,   154,   nil,    59,   154,
292
   154,   nil,   nil,   154,   154,   154,   154,   nil,    94,    94,
293
   nil,   154,    94,    94,   nil,   nil,    94,    94,    94,    94,
294
   nil,    38,    38,   nil,    94,    38,    38,   nil,   nil,    38,
295
    38,    38,    38,   nil,    38,   nil,   nil,    38,    90,    90,
296
    90,   nil,    90,    90,   nil,   nil,    90,    90,    90,    90,
297
   nil,    90,    76,    76,    90,   nil,    76,    76,   nil,   nil,
298
    76,    76,    76,    76,   nil,    27,    27,    76,    76,    27,
299
    27,    27,   nil,    27,    27,    27,    27,   nil,   114,   114,
300
   nil,    27,   114,   114,   nil,   114,   114,   114,   114,   114,
301
    44,    44,   nil,   114,    44,    44,   nil,    44,    44,    44,
302
    44,    44,    74,    74,   nil,   nil,    74,    74,   nil,    74,
303
    74,    74,    74,    74,   113,   113,   nil,   nil,   113,   113,
304
   nil,   113,   113,   113,   113,   113,   129,   129,   nil,   nil,
305
   129,   129,   nil,   129,   129,   129,   129,   129,    88,    88,
306
   nil,   nil,    88,    88,   nil,    88,    88,    88,    88,    88,
307
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
308
     0,     0,    77,    77,   nil,   nil,    77,    77,   nil,    77,
309
    77,    77,    77,    77 ]
310

  
311
racc_action_pointer = [
312
   378,   155,   126,    31,   167,   174,   116,    72,    86,   100,
313
   113,   119,    95,    86,   nil,   nil,   nil,   nil,   nil,   nil,
314
   nil,   nil,   nil,   nil,   nil,   nil,   170,   281,     0,   nil,
315
   nil,   nil,   nil,    92,   nil,   nil,    39,   nil,   237,   nil,
316
    46,    38,    43,   nil,   306,    15,   nil,   nil,   nil,   nil,
317
    11,    -1,   153,   nil,   nil,    59,   -10,   nil,   nil,   198,
318
    22,   nil,   -17,   nil,   nil,   nil,   126,   117,   184,   nil,
319
    78,   -11,    21,    -7,   318,     2,   268,   378,   nil,   nil,
320
    33,   nil,   nil,   nil,   nil,   nil,    59,   nil,   354,    35,
321
   254,   nil,   nil,   nil,   224,   nil,    52,    45,    45,   nil,
322
    54,   nil,    76,   nil,    65,    78,   nil,   nil,    74,   nil,
323
   nil,    77,   -13,   330,   294,   nil,   nil,   105,   nil,   nil,
324
   nil,    95,   140,   nil,   nil,   nil,    96,    17,   nil,   342,
325
   125,   113,   nil,   nil,   -14,   121,    -7,   nil,   128,   143,
326
   146,   141,   154,   -10,   nil,   nil,   nil,   165,   nil,   nil,
327
   154,    45,   nil,   nil,   211,   nil,   173,   nil,   176,   nil,
328
   nil,   nil,   168,   187,   nil,   nil,   nil ]
329

  
330
racc_action_default = [
331
  -109,  -109,  -109,  -109,   -14,  -109,   -20,  -109,  -109,  -109,
332
  -109,  -109,  -109,  -109,   -10,   -95,  -105,  -106,   -77,   -44,
333
  -107,   -11,  -108,   -79,   -43,  -102,  -109,  -109,   -60,  -103,
334
   -55,  -104,   -78,   -68,   -54,   -71,   -45,   -12,  -109,    -1,
335
  -109,  -109,  -109,    -2,  -109,   -22,   -51,   -48,   -50,    -3,
336
   -40,   -41,  -109,   -46,    -4,   -86,    -5,   -88,    -6,   -90,
337
  -109,    -7,   -95,    -8,    -9,   -98,  -100,   -61,   -59,   -56,
338
   -69,  -109,  -109,  -109,  -109,   -75,  -109,  -109,   -57,   -15,
339
  -109,   167,   -73,   -80,   -82,   -21,   -24,   -81,  -109,   -27,
340
  -109,   -83,   -47,   -89,  -109,   -91,  -109,  -100,  -109,   -99,
341
  -101,   -75,   -58,   -52,  -109,  -109,   -64,   -63,   -65,   -76,
342
   -72,   -67,  -109,  -109,  -109,   -26,   -23,  -109,   -29,   -49,
343
   -84,   -42,   -87,   -92,   -94,   -95,  -109,  -109,   -62,  -109,
344
  -109,   -25,   -74,   -28,   -31,  -100,  -109,   -53,   -66,  -109,
345
  -109,   -34,  -109,  -109,   -93,   -96,   -97,  -109,   -18,   -13,
346
   -38,  -109,   -30,   -33,  -109,   -32,   -16,   -19,   -14,   -35,
347
   -36,   -37,  -109,  -109,   -39,   -85,   -17 ]
348

  
349
racc_goto_table = [
350
    39,    67,    70,    73,    38,    66,    69,    24,    37,    57,
351
    59,    36,    55,    67,    99,    90,    85,   157,    69,   108,
352
    83,   134,   111,    76,    49,    53,   141,    70,    73,   150,
353
   118,    89,    45,   155,   159,   149,   140,    21,    14,    19,
354
   119,   102,    64,    63,    61,   124,    70,   104,    58,   132,
355
    83,    56,    97,    83,    54,    93,    43,     5,   131,    95,
356
   116,   nil,    76,   nil,    83,    76,   nil,   127,   nil,    38,
357
   nil,   nil,   nil,   103,   138,   nil,   110,   nil,   nil,   nil,
358
   nil,   nil,   nil,   144,   nil,   nil,   nil,   nil,   nil,    83,
359
    83,   nil,   nil,   nil,    57,   nil,   nil,   122,   nil,   121,
360
   nil,   nil,   nil,   nil,   nil,    83,   nil,   nil,   nil,   nil,
361
   nil,   nil,   nil,   nil,   nil,   135,   nil,   nil,   nil,   nil,
362
   nil,   nil,    93,   nil,   nil,   nil,    70,   161,    38,    70,
363
   162,   160,   137,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
364
   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
365
   nil,   nil,   nil,   nil,   164 ]
366

  
367
racc_goto_check = [
368
     2,    37,    37,    29,    36,    46,    28,    13,    13,    41,
369
    41,    31,    45,    37,    47,    32,    24,    23,    28,    25,
370
    44,    20,    25,    42,     4,     4,    21,    37,    29,    22,
371
    19,    18,    17,    26,    27,    16,    15,    12,    11,    33,
372
    34,    35,    10,     9,     8,    47,    37,    29,     7,    43,
373
    44,     6,    46,    44,     5,    41,     3,     1,    25,    41,
374
    24,   nil,    42,   nil,    44,    42,   nil,    32,   nil,    36,
375
   nil,   nil,   nil,    13,    25,   nil,    41,   nil,   nil,   nil,
376
   nil,   nil,   nil,    47,   nil,   nil,   nil,   nil,   nil,    44,
377
    44,   nil,   nil,   nil,    41,   nil,   nil,    45,   nil,    31,
378
   nil,   nil,   nil,   nil,   nil,    44,   nil,   nil,   nil,   nil,
379
   nil,   nil,   nil,   nil,   nil,    46,   nil,   nil,   nil,   nil,
380
   nil,   nil,    41,   nil,   nil,   nil,    37,    29,    36,    37,
381
    29,    28,    13,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
382
   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
383
   nil,   nil,   nil,   nil,     2 ]
384

  
385
racc_goto_pointer = [
386
   nil,    57,    -4,    50,    17,    46,    42,    38,    33,    31,
387
    29,    37,    35,     5,   nil,   -94,  -105,    26,   -14,   -59,
388
   -97,  -108,  -112,  -133,   -28,   -55,  -110,  -117,   -20,   -24,
389
   nil,     9,   -35,    37,   -50,   -27,     1,   -25,   nil,   nil,
390
   nil,     0,    -5,   -65,   -24,     3,   -10,   -52 ]
391

  
392
racc_goto_default = [
393
   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
394
   nil,   nil,   nil,    48,    41,   nil,   nil,   nil,   nil,   nil,
395
   nil,   nil,   nil,   nil,   nil,    86,   nil,   nil,    30,    34,
396
    50,    51,   nil,    46,    47,   nil,    26,    28,    71,    72,
397
    33,    35,   114,    82,    18,   nil,   nil,   nil ]
398

  
399
racc_token_table = {
400
 false => 0,
401
 Object.new => 1,
402
 :DATETIME => 2,
403
 :RECEIVED => 3,
404
 :MADDRESS => 4,
405
 :RETPATH => 5,
406
 :KEYWORDS => 6,
407
 :ENCRYPTED => 7,
408
 :MIMEVERSION => 8,
409
 :CTYPE => 9,
410
 :CENCODING => 10,
411
 :CDISPOSITION => 11,
412
 :ADDRESS => 12,
413
 :MAILBOX => 13,
414
 :DIGIT => 14,
415
 :ATOM => 15,
416
 "," => 16,
417
 ":" => 17,
418
 :FROM => 18,
419
 :BY => 19,
420
 "@" => 20,
421
 :DOMLIT => 21,
422
 :VIA => 22,
423
 :WITH => 23,
424
 :ID => 24,
425
 :FOR => 25,
426
 ";" => 26,
427
 "<" => 27,
428
 ">" => 28,
429
 "." => 29,
430
 :QUOTED => 30,
431
 :TOKEN => 31,
432
 "/" => 32,
433
 "=" => 33 }
434

  
435
racc_use_result_var = false
436

  
437
racc_nt_base = 34
438

  
439
Racc_arg = [
440
 racc_action_table,
441
 racc_action_check,
442
 racc_action_default,
443
 racc_action_pointer,
444
 racc_goto_table,
445
 racc_goto_check,
446
 racc_goto_default,
447
 racc_goto_pointer,
448
 racc_nt_base,
449
 racc_reduce_table,
450
 racc_token_table,
451
 racc_shift_n,
452
 racc_reduce_n,
453
 racc_use_result_var ]
454

  
455
Racc_token_to_s_table = [
456
'$end',
457
'error',
458
'DATETIME',
459
'RECEIVED',
460
'MADDRESS',
461
'RETPATH',
462
'KEYWORDS',
463
'ENCRYPTED',
464
'MIMEVERSION',
465
'CTYPE',
466
'CENCODING',
467
'CDISPOSITION',
468
'ADDRESS',
469
'MAILBOX',
470
'DIGIT',
471
'ATOM',
472
'","',
473
'":"',
474
'FROM',
475
'BY',
476
'"@"',
477
'DOMLIT',
478
'VIA',
479
'WITH',
480
'ID',
481
'FOR',
482
'";"',
483
'"<"',
484
'">"',
485
'"."',
486
'QUOTED',
487
'TOKEN',
488
'"/"',
489
'"="',
490
'$start',
491
'content',
492
'datetime',
493
'received',
494
'addrs_TOP',
495
'retpath',
496
'keys',
497
'enc',
498
'version',
499
'ctype',
500
'cencode',
501
'cdisp',
502
'addr_TOP',
503
'mbox',
504
'day',
505
'hour',
506
'zone',
507
'from',
508
'by',
509
'via',
510
'with',
511
'id',
512
'for',
513
'received_datetime',
514
'received_domain',
515
'domain',
516
'msgid',
517
'received_addrspec',
518
'routeaddr',
519
'spec',
520
'addrs',
521
'group_bare',
522
'commas',
523
'group',
524
'addr',
525
'mboxes',
526
'addr_phrase',
527
'local_head',
528
'routes',
529
'at_domains',
530
'local',
531
'word',
532
'dots',
533
'domword',
534
'atom',
535
'phrase',
536
'params',
537
'opt_semicolon']
538

  
539
Racc_debug_parser = false
540

  
541
##### racc system variables end #####
542

  
543
 # reduce 0 omitted
544

  
545
module_eval <<'.,.,', 'lib/tmail/parser.y', 16
546
  def _reduce_1( val, _values)
547
 val[1]
548
  end
549
.,.,
550

  
551
module_eval <<'.,.,', 'lib/tmail/parser.y', 17
552
  def _reduce_2( val, _values)
553
 val[1]
554
  end
555
.,.,
556

  
557
module_eval <<'.,.,', 'lib/tmail/parser.y', 18
558
  def _reduce_3( val, _values)
559
 val[1]
560
  end
561
.,.,
562

  
563
module_eval <<'.,.,', 'lib/tmail/parser.y', 19
564
  def _reduce_4( val, _values)
565
 val[1]
566
  end
567
.,.,
568

  
569
module_eval <<'.,.,', 'lib/tmail/parser.y', 20
570
  def _reduce_5( val, _values)
571
 val[1]
572
  end
573
.,.,
574

  
575
module_eval <<'.,.,', 'lib/tmail/parser.y', 21
576
  def _reduce_6( val, _values)
577
 val[1]
578
  end
579
.,.,
580

  
581
module_eval <<'.,.,', 'lib/tmail/parser.y', 22
582
  def _reduce_7( val, _values)
583
 val[1]
584
  end
585
.,.,
586

  
587
module_eval <<'.,.,', 'lib/tmail/parser.y', 23
588
  def _reduce_8( val, _values)
589
 val[1]
590
  end
591
.,.,
592

  
593
module_eval <<'.,.,', 'lib/tmail/parser.y', 24
594
  def _reduce_9( val, _values)
595
 val[1]
596
  end
597
.,.,
598

  
599
module_eval <<'.,.,', 'lib/tmail/parser.y', 25
600
  def _reduce_10( val, _values)
601
 val[1]
602
  end
603
.,.,
604

  
605
module_eval <<'.,.,', 'lib/tmail/parser.y', 26
606
  def _reduce_11( val, _values)
607
 val[1]
608
  end
609
.,.,
610

  
611
module_eval <<'.,.,', 'lib/tmail/parser.y', 27
612
  def _reduce_12( val, _values)
613
 val[1]
614
  end
615
.,.,
616

  
617
module_eval <<'.,.,', 'lib/tmail/parser.y', 36
618
  def _reduce_13( val, _values)
619
                  t = Time.gm(val[3].to_i, val[2], val[1].to_i, 0, 0, 0)
620
                  (t + val[4] - val[5]).localtime
621
  end
622
.,.,
623

  
624
 # reduce 14 omitted
625

  
626
 # reduce 15 omitted
627

  
628
module_eval <<'.,.,', 'lib/tmail/parser.y', 45
629
  def _reduce_16( val, _values)
630
                  (val[0].to_i * 60 * 60) +
631
                  (val[2].to_i * 60)
632
  end
633
.,.,
634

  
635
module_eval <<'.,.,', 'lib/tmail/parser.y', 51
636
  def _reduce_17( val, _values)
637
                  (val[0].to_i * 60 * 60) +
638
                  (val[2].to_i * 60) +
639
                  (val[4].to_i)
640
  end
641
.,.,
642

  
643
module_eval <<'.,.,', 'lib/tmail/parser.y', 56
644
  def _reduce_18( val, _values)
645
                  timezone_string_to_unixtime(val[0])
646
  end
647
.,.,
648

  
649
module_eval <<'.,.,', 'lib/tmail/parser.y', 61
650
  def _reduce_19( val, _values)
651
                  val
652
  end
653
.,.,
654

  
655
 # reduce 20 omitted
656

  
657
module_eval <<'.,.,', 'lib/tmail/parser.y', 67
658
  def _reduce_21( val, _values)
659
                  val[1]
660
  end
661
.,.,
662

  
663
 # reduce 22 omitted
664

  
665
module_eval <<'.,.,', 'lib/tmail/parser.y', 73
666
  def _reduce_23( val, _values)
667
                  val[1]
668
  end
669
.,.,
670

  
671
module_eval <<'.,.,', 'lib/tmail/parser.y', 79
672
  def _reduce_24( val, _values)
673
                  join_domain(val[0])
674
  end
675
.,.,
676

  
677
module_eval <<'.,.,', 'lib/tmail/parser.y', 83
678
  def _reduce_25( val, _values)
679
                  join_domain(val[2])
680
  end
681
.,.,
682

  
683
module_eval <<'.,.,', 'lib/tmail/parser.y', 87
684
  def _reduce_26( val, _values)
685
                  join_domain(val[0])
686
  end
687
.,.,
688

  
689
 # reduce 27 omitted
690

  
691
module_eval <<'.,.,', 'lib/tmail/parser.y', 93
692
  def _reduce_28( val, _values)
693
                  val[1]
694
  end
695
.,.,
696

  
697
module_eval <<'.,.,', 'lib/tmail/parser.y', 98
698
  def _reduce_29( val, _values)
699
                  []
700
  end
701
.,.,
702

  
703
module_eval <<'.,.,', 'lib/tmail/parser.y', 103
704
  def _reduce_30( val, _values)
705
                  val[0].push val[2]
706
                  val[0]
707
  end
708
.,.,
709

  
710
 # reduce 31 omitted
711

  
712
module_eval <<'.,.,', 'lib/tmail/parser.y', 109
713
  def _reduce_32( val, _values)
714
                  val[1]
715
  end
716
.,.,
717

  
718
module_eval <<'.,.,', 'lib/tmail/parser.y', 113
719
  def _reduce_33( val, _values)
720
                  val[1]
721
  end
722
.,.,
723

  
724
 # reduce 34 omitted
725

  
726
module_eval <<'.,.,', 'lib/tmail/parser.y', 119
727
  def _reduce_35( val, _values)
728
                  val[1]
729
  end
730
.,.,
731

  
732
module_eval <<'.,.,', 'lib/tmail/parser.y', 125
733
  def _reduce_36( val, _values)
734
                  val[0].spec
735
  end
736
.,.,
737

  
738
module_eval <<'.,.,', 'lib/tmail/parser.y', 129
739
  def _reduce_37( val, _values)
740
                  val[0].spec
741
  end
742
.,.,
743

  
744
 # reduce 38 omitted
745

  
746
module_eval <<'.,.,', 'lib/tmail/parser.y', 136
747
  def _reduce_39( val, _values)
748
                  val[1]
749
  end
750
.,.,
751

  
752
 # reduce 40 omitted
753

  
754
 # reduce 41 omitted
755

  
756
 # reduce 42 omitted
757

  
758
 # reduce 43 omitted
759

  
760
 # reduce 44 omitted
761

  
762
 # reduce 45 omitted
763

  
764
 # reduce 46 omitted
765

  
766
module_eval <<'.,.,', 'lib/tmail/parser.y', 146
767
  def _reduce_47( val, _values)
768
 [ Address.new(nil, nil) ]
769
  end
770
.,.,
771

  
772
module_eval <<'.,.,', 'lib/tmail/parser.y', 152
773
  def _reduce_48( val, _values)
774
                  val
775
  end
776
.,.,
777

  
778
module_eval <<'.,.,', 'lib/tmail/parser.y', 157
779
  def _reduce_49( val, _values)
780
                  val[0].push val[2]
781
                  val[0]
782
  end
783
.,.,
784

  
785
 # reduce 50 omitted
786

  
787
 # reduce 51 omitted
788

  
789
module_eval <<'.,.,', 'lib/tmail/parser.y', 165
790
  def _reduce_52( val, _values)
791
                  val
792
  end
793
.,.,
794

  
795
module_eval <<'.,.,', 'lib/tmail/parser.y', 170
796
  def _reduce_53( val, _values)
797
                  val[0].push val[2]
798
                  val[0]
799
  end
800
.,.,
801

  
802
 # reduce 54 omitted
803

  
804
 # reduce 55 omitted
805

  
806
module_eval <<'.,.,', 'lib/tmail/parser.y', 178
807
  def _reduce_56( val, _values)
808
                  val[1].phrase = Decoder.decode(val[0])
809
                  val[1]
810
  end
811
.,.,
812

  
813
 # reduce 57 omitted
814

  
815
module_eval <<'.,.,', 'lib/tmail/parser.y', 185
816
  def _reduce_58( val, _values)
817
                  AddressGroup.new(val[0], val[2])
818
  end
819
.,.,
820

  
821
module_eval <<'.,.,', 'lib/tmail/parser.y', 185
822
  def _reduce_59( val, _values)
823
 AddressGroup.new(val[0], [])
824
  end
825
.,.,
826

  
827
module_eval <<'.,.,', 'lib/tmail/parser.y', 188
828
  def _reduce_60( val, _values)
829
 val[0].join('.')
830
  end
831
.,.,
832

  
833
module_eval <<'.,.,', 'lib/tmail/parser.y', 189
834
  def _reduce_61( val, _values)
835
 val[0] << ' ' << val[1].join('.')
836
  end
837
.,.,
838

  
839
module_eval <<'.,.,', 'lib/tmail/parser.y', 196
840
  def _reduce_62( val, _values)
841
                  val[2].routes.replace val[1]
842
                  val[2]
843
  end
844
.,.,
845

  
846
module_eval <<'.,.,', 'lib/tmail/parser.y', 200
847
  def _reduce_63( val, _values)
848
                  val[1]
849
  end
850
.,.,
851

  
852
 # reduce 64 omitted
853

  
854
module_eval <<'.,.,', 'lib/tmail/parser.y', 203
855
  def _reduce_65( val, _values)
856
 [ val[1].join('.') ]
857
  end
858
.,.,
859

  
860
module_eval <<'.,.,', 'lib/tmail/parser.y', 204
861
  def _reduce_66( val, _values)
862
 val[0].push val[3].join('.'); val[0]
863
  end
864
.,.,
865

  
866
module_eval <<'.,.,', 'lib/tmail/parser.y', 206
867
  def _reduce_67( val, _values)
868
 Address.new( val[0], val[2] )
869
  end
870
.,.,
871

  
872
module_eval <<'.,.,', 'lib/tmail/parser.y', 207
873
  def _reduce_68( val, _values)
874
 Address.new( val[0], nil )
875
  end
876
.,.,
877

  
878
 # reduce 69 omitted
879

  
880
module_eval <<'.,.,', 'lib/tmail/parser.y', 210
881
  def _reduce_70( val, _values)
882
 val[0].push ''; val[0]
883
  end
884
.,.,
885

  
886
module_eval <<'.,.,', 'lib/tmail/parser.y', 213
887
  def _reduce_71( val, _values)
888
 val
889
  end
890
.,.,
891

  
892
module_eval <<'.,.,', 'lib/tmail/parser.y', 222
893
  def _reduce_72( val, _values)
894
                  val[1].times do
895
                    val[0].push ''
896
                  end
897
                  val[0].push val[2]
898
                  val[0]
899
  end
900
.,.,
901

  
902
module_eval <<'.,.,', 'lib/tmail/parser.y', 224
903
  def _reduce_73( val, _values)
904
 val
905
  end
906
.,.,
907

  
908
module_eval <<'.,.,', 'lib/tmail/parser.y', 233
909
  def _reduce_74( val, _values)
910
                  val[1].times do
911
                    val[0].push ''
912
                  end
913
                  val[0].push val[2]
914
                  val[0]
915
  end
916
.,.,
917

  
918
module_eval <<'.,.,', 'lib/tmail/parser.y', 234
919
  def _reduce_75( val, _values)
920
 0
921
  end
922
.,.,
923

  
924
module_eval <<'.,.,', 'lib/tmail/parser.y', 235
925
  def _reduce_76( val, _values)
926
 val[0] + 1
927
  end
928
.,.,
929

  
930
 # reduce 77 omitted
931

  
932
 # reduce 78 omitted
933

  
934
 # reduce 79 omitted
935

  
936
 # reduce 80 omitted
937

  
938
 # reduce 81 omitted
939

  
940
 # reduce 82 omitted
941

  
942
 # reduce 83 omitted
943

  
944
 # reduce 84 omitted
945

  
946
module_eval <<'.,.,', 'lib/tmail/parser.y', 253
947
  def _reduce_85( val, _values)
948
                  val[1] = val[1].spec
949
                  val.join('')
950
  end
951
.,.,
952

  
953
module_eval <<'.,.,', 'lib/tmail/parser.y', 254
954
  def _reduce_86( val, _values)
955
 val
956
  end
957
.,.,
958

  
959
module_eval <<'.,.,', 'lib/tmail/parser.y', 255
960
  def _reduce_87( val, _values)
961
 val[0].push val[2]; val[0]
962
  end
963
.,.,
964

  
965
 # reduce 88 omitted
966

  
967
module_eval <<'.,.,', 'lib/tmail/parser.y', 258
968
  def _reduce_89( val, _values)
969
 val[0] << ' ' << val[1]
970
  end
971
.,.,
972

  
973
module_eval <<'.,.,', 'lib/tmail/parser.y', 265
974
  def _reduce_90( val, _values)
975
                  val.push nil
976
                  val
977
  end
978
.,.,
979

  
980
module_eval <<'.,.,', 'lib/tmail/parser.y', 269
981
  def _reduce_91( val, _values)
982
                  val
983
  end
984
.,.,
985

  
986
module_eval <<'.,.,', 'lib/tmail/parser.y', 274
987
  def _reduce_92( val, _values)
988
                  [ val[0].to_i, val[2].to_i ]
989
  end
990
.,.,
991

  
992
module_eval <<'.,.,', 'lib/tmail/parser.y', 279
993
  def _reduce_93( val, _values)
994
                  [ val[0].downcase, val[2].downcase, decode_params(val[3]) ]
995
  end
996
.,.,
997

  
998
module_eval <<'.,.,', 'lib/tmail/parser.y', 283
999
  def _reduce_94( val, _values)
1000
                  [ val[0].downcase, nil, decode_params(val[1]) ]
1001
  end
1002
.,.,
1003

  
1004
module_eval <<'.,.,', 'lib/tmail/parser.y', 288
1005
  def _reduce_95( val, _values)
1006
                  {}
1007
  end
1008
.,.,
1009

  
1010
module_eval <<'.,.,', 'lib/tmail/parser.y', 293
1011
  def _reduce_96( val, _values)
1012
                  val[0][ val[2].downcase ] = ('"' + val[4].to_s + '"')
1013
                  val[0]
1014
  end
1015
.,.,
1016

  
1017
module_eval <<'.,.,', 'lib/tmail/parser.y', 298
1018
  def _reduce_97( val, _values)
1019
                  val[0][ val[2].downcase ] = val[4]
1020
                  val[0]
1021
  end
1022
.,.,
1023

  
1024
module_eval <<'.,.,', 'lib/tmail/parser.y', 303
1025
  def _reduce_98( val, _values)
1026
                  val[0].downcase
1027
  end
1028
.,.,
1029

  
1030
module_eval <<'.,.,', 'lib/tmail/parser.y', 308
1031
  def _reduce_99( val, _values)
1032
                  [ val[0].downcase, decode_params(val[1]) ]
1033
  end
1034
.,.,
1035

  
1036
 # reduce 100 omitted
1037

  
1038
 # reduce 101 omitted
1039

  
1040
 # reduce 102 omitted
1041

  
1042
 # reduce 103 omitted
1043

  
1044
 # reduce 104 omitted
1045

  
1046
 # reduce 105 omitted
1047

  
1048
 # reduce 106 omitted
1049

  
1050
 # reduce 107 omitted
1051

  
1052
 # reduce 108 omitted
1053

  
1054
 def _reduce_none( val, _values)
1055
  val[0]
1056
 end
1057

  
1058
  end   # class Parser
1059

  
1060
end   # module TMail
trunk/lib/vendor/tmail-1.2.7/tmail/encode.rb
1
#--
2
# = COPYRIGHT:
3
#
4
#   Copyright (c) 1998-2003 Minero Aoki <[email protected]>
5
#
6
#   Permission is hereby granted, free of charge, to any person obtaining
7
#   a copy of this software and associated documentation files (the
8
#   "Software"), to deal in the Software without restriction, including
9
#   without limitation the rights to use, copy, modify, merge, publish,
10
#   distribute, sublicense, and/or sell copies of the Software, and to
11
#   permit persons to whom the Software is furnished to do so, subject to
12
#   the following conditions:
13
#
14
#   The above copyright notice and this permission notice shall be
15
#   included in all copies or substantial portions of the Software.
16
#
17
#   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
#   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
#   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
#   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
#   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
#   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
#   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
#
25
#   Note: Originally licensed under LGPL v2+. Using MIT license for Rails
26
#   with permission of Minero Aoki.
27
#++
28
#:stopdoc:
29
require 'nkf'
30
require 'tmail/base64'
31
require 'tmail/stringio'
32
require 'tmail/utils'
33
#:startdoc:
34

  
35

  
36
module TMail
37
  
38
  #:stopdoc:
39
  class << self
40
    attr_accessor :KCODE
41
  end
42
  self.KCODE = 'NONE'
43

  
44
  module StrategyInterface
45

  
46
    def create_dest( obj )
47
      case obj
48
      when nil
49
        StringOutput.new
50
      when String
51
        StringOutput.new(obj)
52
      when IO, StringOutput
53
        obj
54
      else
55
        raise TypeError, 'cannot handle this type of object for dest'
56
      end
57
    end
58
    module_function :create_dest
59

  
60
    #:startdoc:
61
    # Returns the TMail object encoded and ready to be sent via SMTP etc.
62
    # You should call this before you are packaging up your  email to
63
    # correctly escape all the values that need escaping in the email, line
64
    # wrap the email etc.
65
    # 
66
    # It is also a good idea to call this before you marshal or serialize
67
    # a TMail object.
68
    # 
69
    # For Example:
70
    # 
71
    #  email = TMail::Load(my_email_file)
72
    #  email_to_send = email.encoded
73
    def encoded( eol = "\r\n", charset = 'j', dest = nil )
74
      accept_strategy Encoder, eol, charset, dest
75
    end
76

  
77
    # Returns the TMail object decoded and ready to be used by you, your
78
    # program etc.
79
    # 
80
    # You should call this before you are packaging up your  email to
81
    # correctly escape all the values that need escaping in the email, line
82
    # wrap the email etc.
83
    # 
84
    # For Example:
85
    # 
86
    #  email = TMail::Load(my_email_file)
87
    #  email_to_send = email.encoded
88
    def decoded( eol = "\n", charset = 'e', dest = nil )
89
      # Turn the E-Mail into a string and return it with all
90
      # encoded characters decoded.  alias for to_s
91
      accept_strategy Decoder, eol, charset, dest
92
    end
93

  
94
    alias to_s decoded
95

  
96
    def accept_strategy( klass, eol, charset, dest = nil ) #:nodoc:
97
      dest ||= ''
98
      accept klass.new( create_dest(dest), charset, eol )
99
      dest
100
    end
101

  
102
  end
103

  
104
  #:stopdoc:
105

  
106
  ###
107
  ### MIME B encoding decoder
108
  ###
109

  
110
  class Decoder
111

  
112
    include TextUtils
113

  
114
    encoded = '=\?(?:iso-2022-jp|euc-jp|shift_jis)\?[QB]\?[a-z0-9+/=]+\?='
115
    ENCODED_WORDS = /#{encoded}(?:\s+#{encoded})*/i
116
    SPACER       = "\t"
117

  
118
    OUTPUT_ENCODING = {
119
      'EUC'  => 'e',
120
      'SJIS' => 's',
121
    }
122

  
123
    def self.decode( str, encoding = nil )
124
      encoding ||= (OUTPUT_ENCODING[TMail.KCODE] || 'j')
125
      opt = '-mS' + encoding
126
      str.gsub(ENCODED_WORDS) {|s| NKF.nkf(opt, s) }
127
    end
128

  
129
    def initialize( dest, encoding = nil, eol = "\n" )
130
      @f = StrategyInterface.create_dest(dest)
131
      @encoding = (/\A[ejs]/ === encoding) ? encoding[0,1] : nil
132
      @eol = eol
133
    end
134

  
135
    def decode( str )
136
      self.class.decode(str, @encoding)
137
    end
138
    private :decode
139

  
140
    def terminate
141
    end
142

  
143
    def header_line( str )
144
      @f << decode(str)
145
    end
146

  
147
    def header_name( nm )
148
      @f << nm << ': '
149
    end
150

  
151
    def header_body( str )
152
      @f << decode(str)
153
    end
154

  
155
    def space
156
      @f << ' '
157
    end
158

  
159
    alias spc space
160

  
161
    def lwsp( str )
162
      @f << str
163
    end
164

  
165
    def meta( str )
166
      @f << str
167
    end
168

  
169
    def puts_meta( str )
170
      @f << str
171
    end
172

  
173
    def text( str )
174
      @f << decode(str)
175
    end
176

  
177
    def phrase( str )
178
      @f << quote_phrase(decode(str))
179
    end
180

  
181
    def kv_pair( k, v )
182
      v = dquote(v) unless token_safe?(v)
183
      @f << k << '=' << v
184
    end
185

  
186
    def puts( str = nil )
187
      @f << str if str
188
      @f << @eol
189
    end
190

  
191
    def write( str )
192
      @f << str
193
    end
194

  
195
  end
196

  
197

  
198
  ###
199
  ### MIME B-encoding encoder
200
  ###
201

  
202
  #
203
  # FIXME: This class can handle only (euc-jp/shift_jis -> iso-2022-jp).
204
  #
205
  class Encoder
206

  
207
    include TextUtils
208

  
209
    BENCODE_DEBUG = false unless defined?(BENCODE_DEBUG)
210

  
211
    def Encoder.encode( str )
212
      e = new()
213
      e.header_body str
214
      e.terminate
215
      e.dest.string
216
    end
217

  
218
    SPACER       = "\t"
219
    MAX_LINE_LEN = 78
220
    RFC_2822_MAX_LENGTH = 998
221

  
222
    OPTIONS = {
223
      'EUC'  => '-Ej -m0',
224
      'SJIS' => '-Sj -m0',
225
      'UTF8' => nil,      # FIXME
226
      'NONE' => nil
227
    }
228

  
229
    def initialize( dest = nil, encoding = nil, eol = "\r\n", limit = nil )
230
      @f = StrategyInterface.create_dest(dest)
231
      @opt = OPTIONS[TMail.KCODE]
232
      @eol = eol
233
      @folded = false
234
      @preserve_quotes = true
235
      reset
236
    end
237

  
238
    def preserve_quotes=( bool )
239
      @preserve_quotes
240
    end
241

  
242
    def preserve_quotes
243
      @preserve_quotes
244
    end
245

  
246
    def normalize_encoding( str )
247
      if @opt
248
      then NKF.nkf(@opt, str)
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff