Permalink
Browse files

Receiving mail

  • Loading branch information...
1 parent fb61e60 commit 355ad8a170b30e8061e953623b305dd22f59f9a4 @rust rust committed Jan 18, 2011
View
1 .rspec
@@ -2,4 +2,3 @@
--format
progress
mtime
--b
View
@@ -39,7 +39,7 @@ def self.external_to_unicodecr_docomo(str)
end
end
- # +str+ のなかでDoCoMo絵文字をUnicode数値文字参照に置換した文字列を返す
+ # +str+ のなかでau絵文字をUnicode数値文字参照に置換した文字列を返す
def self.external_to_unicodecr_au(str)
str.gsub(AU_SJIS_REGEXP) do |match|
sjis = match.unpack('n').first
@@ -49,11 +49,12 @@ def self.external_to_unicodecr_au(str)
end
# +str+ のなかでau絵文字をUnicode数値文字参照に置換した文字列を返す。(メール専用)
- def self.external_to_unicodecr_au_mail(str)
+ def self.external_to_unicodecr_au_mail(in_str)
+ str = Jpmobile::Util.ascii_8bit(in_str)
str.gsub(AU_EMAILJIS_REGEXP) do |match|
jis = match.unpack('n').first
unicode = AU_EMAILJIS_TO_UNICODE[jis]
- unicode ? ("&#x%04x;"%unicode) : match
+ unicode ? Jpmobile::Util.ascii_8bit("\x1b\x28\x42&#x%04x;\x1b\x24\x42"%unicode) : match
end
end
@@ -65,6 +66,14 @@ def self.external_to_unicodecr_softbank(str)
"&#x%04x;" % (unicode+0x1000)
end
end
+ def self.external_to_unicodecr_softbank_sjis(str)
+ # SoftBank Shift_JIS
+ str.gsub(SOFTBANK_SJIS_REGEXP) do |match|
+ sjis = match.unpack('n').first
+ unicode = SOFTBANK_SJIS_TO_UNICODE[sjis]
+ "&#x%04x;" % (unicode+0x1000)
+ end
+ end
def self.external_to_unicodecr_vodafone(str)
external_to_unicodecr_softbank(str)
end
View
@@ -1,6 +1,12 @@
# -*- coding: utf-8 -*-
require 'mail'
+module Jpmobile
+ module Mail
+ module_function
+ end
+end
+
module Mail
# encoding patch
if self.const_defined?(:Ruby19)
@@ -12,18 +18,15 @@ def self.b_value_decode(str)
str = self.decode_base64(match[2])
str.force_encoding(fix_encoding(encoding))
end
- str
+ # if str contains some emoticon, the following line raises Encoding error
+ str.encode("utf-8", :invalid => :replace, :replace => "") rescue Jpmobile::Util.ascii_8bit(str)
end
end
end
class Message
attr_accessor :mobile
- def mobile=(m)
- @mobile = m
- end
-
def encoded_with_jpmobile
if @mobile
header['subject'].mobile = @mobile
@@ -43,8 +46,75 @@ def encoded_with_jpmobile
end
end
+ def parse_message_with_jpmobile
+ parse_message_without_jpmobile
+
+ if !multipart? and self.header['Content-Type']
+ self.body.charset = case self.header['Content-Type'].value
+ when /iso-2022-jp/i
+ "ISO-2022-JP"
+ when /shift_jis/i
+ "Shift_JIS"
+ else
+ "UTF-8"
+ end
+ end
+ self.header['subject'].mobile = @mobile if self.header['subject']
+ end
+
+ def init_with_string_with_jpmobile(string)
+ # Jpmobile::Mobile class from 'From: ' header
+ s = Jpmobile::Util.ascii_8bit(string)
+ mobile_class = nil
+ s.split(/\n|\r/).each do |line|
+ break if line =~ /^From:/ and mobile_class = Jpmobile::Email.detect(line)
+ end
+
+ @mobile = (mobile_class || Jpmobile::Mobile::AbstractMobile).new(nil, nil)
+
+ init_with_string_without_jpmobile(s)
+
+ self.body.mobile = @mobile
+ self.body.set_encoding_jpmobile
+ end
+
+ def process_body_raw_with_jpmobile
+ process_body_raw_without_jpmobile
+
+ self.body.mobile = @mobile
+ end
+
alias_method :encoded_without_jpmobile, :encoded
alias_method :encoded, :encoded_with_jpmobile
+
+ alias_method :parse_message_without_jpmobile, :parse_message
+ alias_method :parse_message, :parse_message_with_jpmobile
+
+ alias_method :init_with_string_without_jpmobile, :init_with_string
+ alias_method :init_with_string, :init_with_string_with_jpmobile
+
+ alias_method :process_body_raw_without_jpmobile, :process_body_raw
+ alias_method :process_body_raw, :process_body_raw_with_jpmobile
+ end
+
+ class Part
+ def parse_message_with_jpmobile
+ parse_message_without_jpmobile
+
+ unless multipart?
+ self.body.charset = case self.header['Content-Type'].value
+ when /iso-2022-jp/i
+ "ISO-2022-JP"
+ when /shift_jis/i
+ "Shift_JIS"
+ else
+ "UTF-8"
+ end
+ end
+ end
+
+ alias_method :parse_message_without_jpmobile, :parse_message
+ alias_method :parse_message, :parse_message_with_jpmobile
end
class Body
@@ -58,18 +128,55 @@ def encoded_with_jpmobile(transfer_encoding = '8bit')
encoded_without_jpmobile(transfer_encoding)
end
end
+ def decoded_with_jpmobile
+ if @mobile and !multipart?
+ @raw_source = @mobile.to_mail_internal(@raw_source, nil) unless @jpmobile_decoded
+ @jpmobile_decoded = true
+ end
+
+ if @charset
+ @raw_source = Jpmobile::Util.force_encode(@raw_source, @charset, Jpmobile::Util::UTF8)
+ end
+
+ decoded_without_jpmobile
+ end
+
+ # fix charset
+ def set_charset_with_jpmobile
+ @charset ||= only_us_ascii? ? 'US-ASCII' : nil
+ end
+
+ # set encoding to @raw_source in init
+ def set_encoding_jpmobile
+ @raw_source = Jpmobile::Util.set_encoding(@raw_source, @charset)
+ end
alias_method :encoded_without_jpmobile, :encoded
alias_method :encoded, :encoded_with_jpmobile
+
+ alias_method :decoded_without_jpmobile, :decoded
+ alias_method :decoded, :decoded_with_jpmobile
+
+ alias_method :set_charset_without_jpmobile, :set_charset
+ alias_method :set_charset, :set_charset_with_jpmobile
end
class UnstructuredField
attr_accessor :mobile
+
+ def do_decode
+ result = value.blank? ? nil : Encodings.decode_encode(value, :decode)
+
+ result = @mobile.to_mail_internal(result, value) if @mobile
+
+ result.encode!(value.encoding || "UTF-8") if RUBY_VERSION >= '1.9' && !result.blank?
+ result
+ end
end
# for subject
class SubjectField < UnstructuredField
- # not folding subject
+ # FIXME: not folding subject -> folding
def encoded_with_jpmobile
if @mobile
# convert encoding
@@ -79,7 +186,14 @@ def encoded_with_jpmobile
end
end
+ def decoded_with_jpmobile
+ decoded_without_jpmobile
+ end
+
alias_method :encoded_without_jpmobile, :encoded
alias_method :encoded, :encoded_with_jpmobile
+
+ alias_method :decoded_without_jpmobile, :decoded
+ alias_method :decoded, :decoded_with_jpmobile
end
end
@@ -90,6 +90,9 @@ def utf8_to_mail_encode(str)
str
end
end
+ def to_mail_internal(str, val)
+ str
+ end
# リクエストがこのクラスに属するか調べる
# メソッド名に関して非常に不安
@@ -115,6 +115,15 @@ def mail_charset
"ISO-2022-JP"
end
+ def to_mail_internal(str, val)
+ if Jpmobile::Util.jis?(str) or Jpmobile::Util.ascii_8bit?(str)
+ # 絵文字を数値参照に変換
+ str = Jpmobile::Emoticon.external_to_unicodecr_au_mail(Jpmobile::Util.jis(str))
+ str = Jpmobile::Util.jis_to_utf8(Jpmobile::Util.jis(str))
+ end
+ str
+ end
+
private
def to_mail_encoding(str)
str = Jpmobile::Emoticon.utf8_to_unicodecr(str)
@@ -105,6 +105,14 @@ def to_mail_body(str)
def mail_charset
"Shift_JIS"
end
+ def to_mail_internal(str, val)
+ if Jpmobile::Util.shift_jis?(str) or Jpmobile::Util.ascii_8bit?(str)
+ # 絵文字を数値参照に変換
+ str = Jpmobile::Emoticon.external_to_unicodecr_docomo(Jpmobile::Util.sjis(str))
+ end
+
+ str
+ end
# i-mode ブラウザのバージョンを返す。
# http://labs.unoh.net/2009/07/i_20.html
@@ -69,6 +69,14 @@ def to_mail_body(str)
def mail_charset
"Shift_JIS"
end
+ def to_mail_internal(str, val)
+ if Jpmobile::Util.shift_jis?(str) or Jpmobile::Util.ascii_8bit?(str)
+ # 絵文字を数値参照に変換
+ str = Jpmobile::Emoticon.external_to_unicodecr_softbank_sjis(Jpmobile::Util.sjis(str))
+ end
+
+ str
+ end
private
def to_mail_encoding(str)
View
@@ -181,5 +181,106 @@ def wavedash_to_fullwidth_tilde(utf8_str)
def fullwidth_tilde_to_wavedash(utf8_str)
utf8_str.gsub(FULLWIDTH_TILDE, WAVE_DASH)
end
+
+ def force_encode(str, from, to)
+ s = str.dup
+
+ if Object.const_defined?(:Encoding)
+ to = SJIS if to =~ /shift_jis/i
+
+ to_enc = ::Encoding.find(to)
+ return str if s.encoding == to_enc
+
+ from_enc = ::Encoding.find(from)
+
+ s.force_encoding(from) unless s.encoding == from_enc
+
+ s.encode(to)
+ else
+ opt = case from
+ when /iso-2022-jp/i
+ "-Jx"
+ when /shift_jis/i
+ "-Sx"
+ when /utf-8/i
+ "-Wx"
+ else
+ ""
+ end
+ opt += case to
+ when /iso-2022-jp/i
+ "-j"
+ when /shift_jis/i
+ "-s"
+ when /utf-8/i
+ "-w"
+ else
+ ""
+ end
+ NKF.nkf(opt, str)
+ end
+ end
+
+ def set_encoding(str, encoding)
+ if encoding and Object.const_defined?(:Encoding)
+ str.force_encoding(encoding)
+ end
+
+ str
+ end
+
+ def extract_charset(str)
+ case str
+ when /iso-2022-jp/i
+ "ISO-2022-JP"
+ when /shift_jis/i
+ "Shift_JIS"
+ when /utf-8/i
+ "UTF-8"
+ else
+ ""
+ end
+ end
+
+ def detect_encoding(str)
+ if Object.const_defined?(:Encoding)
+ case str.encoding
+ when ::Encoding::ISO2022_JP
+ JIS
+ when ::Encoding::Shift_JIS, ::Encoding::Windows_31J, ::Encoding::CP932
+ SJIS
+ when ::Encoding::UTF_8
+ UTF8
+ when ::Encoding::ASCII_8BIT
+ BINARY
+ else
+ BINARY
+ end
+ else
+ case NKF.guess(str)
+ when NKF::SJIS
+ SJIS
+ when NKF::JIS
+ JIS
+ when NKF::UTF8
+ UTF8
+ else
+ BINARY
+ end
+ end
+ end
+
+ def ascii_8bit?(str)
+ detect_encoding(str) == BINARY
+ end
+ def utf8?(str)
+ detect_encoding(str) == UTF8
+ end
+ def shift_jis?(str)
+ detect_encoding(str) == SJIS
+ end
+ def jis?(str)
+ detect_encoding(str) == JIS
+ end
end
end
Oops, something went wrong.

0 comments on commit 355ad8a

Please sign in to comment.