class Rack::Ketai::Carrier::Softbank::Filter

Constants

EMOJIID_TO_EMOJI

単にEMOJI_TO_EMOJIID#index を使うと、 1つの絵文字が複数のIDに割り当てられている(DoCoMo SJIS-F97A など)場合 見つからなくなる 逆にEMOJIID_TO_EMOJIだけだと複数絵文字の組み合わせによるものがめんどくさい(たぶん)

EMOJI_TO_EMOJIID
WEBCODE_TO_EMOJI

Public Instance Methods

inbound(env) click to toggle source
# File lib/egalite/keitai/rack/ketai/carrier/softbank.rb, line 13
def inbound(env)
  # softbank UTF-8バイナリ(Unicode) -> 絵文字ID表記
  request = Rack::Request.new(env)
  
  request.params  # 最低でも1回呼んでないと query_stringが未設定

  converter = lambda do |value|
    # まずウェブコードを変換
    value = value.gsub(/\x1B\$([GEFOPQ])([\x21-\x7E]+)\x0F/u) do |match|
      head = $1
      $2.split(//u).collect { |b| WEBCODE_TO_EMOJI[head+b]}
    end

    # UTF-8バイナリから絵文字IDに
    value.gsub(emoji_utf8_regexp) do |match|
      format("[e:%03X]", EMOJI_TO_EMOJIID[match])
    end
  end
  deep_apply(request.env["rack.request.query_hash"], &converter)
  deep_apply(request.env["rack.request.form_hash"], &converter)
  
  # 文字コード変換
  super(request.env)
end
outbound(status, headers, body) click to toggle source
# File lib/egalite/keitai/rack/ketai/carrier/softbank.rb, line 38
def outbound(status, headers, body)
  status, headers, body = super

  return [status, headers, body] unless body[0]

  body = body.collect do |str|
    str.gsub(/\[e:([0-9A-F]{3})\]/) do |match|
      emojiid = $1.scanf('%X').first
      utf8str = EMOJIID_TO_EMOJI[emojiid]
      if utf8str
        # 絵文字があるので差替え
        utf8str.split(//u).collect { |b| "\x1B$"+WEBCODE_TO_EMOJI.index(b)+"\x0F" }.join("")
      else
        # 絵文字がないので代替文字列
        emoji_data = EMOJI_DATA[emojiid]
        emoji_data[:fallback] || emoji_data[:name] || '〓'
      end
    end
  end
  
  content = (body.is_a?(Array) ? body[0] : body).to_s
  headers['Content-Length'] = (content.respond_to?(:bytesize) ? content.bytesize : content.size).to_s if headers.member?('Content-Length')
  
  [status, headers, body]
end

Private Instance Methods

emoji_utf8_regexp() click to toggle source

絵文字コード -> 絵文字ID 対応表から、絵文字コード検出用の正規表現をつくる 複数の絵文字の組み合わせのものを前におくことで そっちを優先的にマッチさせる

# File lib/egalite/keitai/rack/ketai/carrier/softbank.rb, line 68
def emoji_utf8_regexp
  @emoji_utf8_regexp if @emoji_utf8_regexp
  @emoji_utf8_regexp = Regexp.union(*EMOJI_TO_EMOJIID.keys.sort_by{ |codes| - codes.size }.collect{ |utf8str| Regexp.new(Regexp.escape(utf8str), nil)})
end