Mobile on Rails をSoftBank のあれな絵文字仕様に対応させた
また、SoftBank(Vodafone)の3G携帯にはSJISの外字領域を使用して絵文字を送出する機種が存在します。それらの機種については現在未対応(絵文字は全て削除される)です。
Young risk taker.: [Rails] SoftBank携帯からの制御文字を含む入力の変換に関するバグFix (Mobile on Rails)
ということで、あれな仕様のSoftBank の絵文字を扱えるようにした。
host /home/mhag/svn_work/foo% svn diff -r2450:HEAD Index: vendor/plugins/mobile_on_rails/lib/mobile/emoji/softbank.rb =================================================================== --- vendor/plugins/mobile_on_rails/lib/mobile/emoji/softbank.rb (revision 2450) +++ vendor/plugins/mobile_on_rails/lib/mobile/emoji/softbank.rb (revision 2451) @@ -14,13 +14,34 @@ len = bytes.length ret = '' while i < len do - if bytes[i] != 0x1b # Not emoticons + if bytes[i] != 0x1b && bytes[i] != 0xf9 && bytes[i] != 0xf7 && bytes[i] != 0xfb # Not emoticons # Multibyte characters if (bytes[i] > 0x80 && bytes[i] < 0xa0) || (bytes[i] > 0xdf && bytes[i] < 0xf0) ret += [sprintf("%x%x", bytes[i], bytes[i+=1])].pack('H4') else # Single byte character ret += [bytes[i]].pack('C') end + elsif bytes[i] == 0xf9 || bytes[i] == 0xf7 || bytes[i] == 0xfb + code_area = bytes[i] + sjis = bytes[i + 1] + + # Begin of web code + emoji_bytes = [0x24] + + emoji_bytes << "G".unpack('C')[0] if code_area == 0xf9 && (0x41 .. 0x9b) === sjis + emoji_bytes << "E".unpack('C')[0] if code_area == 0xf7 && (0x41 .. 0x9b) === sjis + emoji_bytes << "F".unpack('C')[0] if code_area == 0xf7 && (0xa1 .. 0xf3) === sjis + emoji_bytes << "O".unpack('C')[0] if code_area == 0xf9 && (0xa1 .. 0xed) === sjis + emoji_bytes << "P".unpack('C')[0] if code_area == 0xfb && (0x41 .. 0x9b) === sjis + emoji_bytes << "Q".unpack('C')[0] if code_area == 0xfb && (0xa1 .. 0xd7) === sjis + + emoji_bytes << (sjis - 0x20) if (0x41 .. 0x7e) === sjis + emoji_bytes << (sjis - 0x21) if (0x80 .. 0x9b) === sjis + emoji_bytes << (sjis - 0x80) if (0xa1 .. 0xed) === sjis + + # pack('C3') だと、vodafone 絵文字のときにエラー(GEFOPQ が含まれないため) + ret += "__SB_#{emoji_bytes.pack('C*')}__" + i += 1 else emoji_bytes = [] emoji_bytes << bytes[i] while bytes[i+=1] != 0x0f Index: vendor/plugins/mobile_on_rails/lib/mobile/controller.rb =================================================================== --- vendor/plugins/mobile_on_rails/lib/mobile/controller.rb (revision 2450) +++ vendor/plugins/mobile_on_rails/lib/mobile/controller.rb (revision 2451) @@ -83,6 +83,24 @@ def after_filter_for_mobile if request && request.mobile? response.body = NKF.nkf('-Ws -m0 -x', response.body) + + p = /__SB_\$([GEFOPQ])([^_]+)__/ + + h_map = { + """ => "\"", + "<" => "<", + ">" => ">", + "&" => "&", + } + + response.body.gsub!(p) do |match| + if h_map.has_key?($2) + "__SB_\$#{$1}#{h_map[$2]}__" + else + match + end + end + if request.mobile_carrier == ActionController::Mobile::DoCoMo response.body = response.body.to_emoji_from_internal_encode(:to => Emoji::DoCoMo) elsif request.mobile_carrier == ActionController::Mobile::AU
softbank.rb が主な修正対象。
ソフトバンクの絵文字を検出する正規表現 | ke-tai.org - インフィニットループ
SoftBankの一部機種の絵文字はSJIS外字領域を使用しているらしい - 覇王色を求めて
SoftBank 絵文字一覧
SoftBank 技術資料(HTML 編 211ページ以降)
を参考にして、Shift_JIS の外字領域に割り当てられている絵文字コードを
Mobile on Rails が扱っているウェブコードっぽい近い形に変換する処理を加えた。
(例. 0xF90x41 ⇒ __SB_$G!__)
実はこれだけだとE002 やE01C, E01E(絵文字一覧参照)などの絵文字を扱ったときにうまくない。
上記の絵文字はMobile on Rails によって、それぞれ以下のように変換される。
E002 ⇒ __SB_$"!__ E01C ⇒ __SB_$<!__ E01E ⇒ __SB_$>!__
これらは出力時に h() によるエスケープの対象となる(404 Not Found)ため
絵文字の表示、変換が行われなくなってしまう。
この問題を解決するために、controller.rb にも修正を加えた。
コードを見て分かるとおり、一度 h() でエスケープされた文字列のうち
SoftBank の絵文字になりうるものだけはエスケープを解除している。
かなり無駄な処理ではあるが、極力修正範囲を狭くする(アプリには手を入れない)ためと割り切った。
この件はSoftBank のあれな絵文字仕様とは関係なく、以前から存在していたのだと思う。