Google App Engine(Python)でどう絵文字を扱うか悩む
Google App Engine上のサービスで絵文字対応をしたい。2010年12月現在。
「各キャリアで書き込んだ文字列が、そのまま表示される。」「他キャリアで書き込んだ文字列が、なるべく再現できる。」の2つを実現したい。 django-bpmobileでは、au/softbankの絵文字をすべてDoCoMoの絵文字に変換している。変換できない絵文字はそのままのようだ。 django-bpmobileのアプローチでは、前者の条件は満たすが、後者の条件は満たせないと思う。
emoji-pythonライブラリを使うという手もある。 http://code.google.com/p/emoji-python/ しかし、Unicode 6.0では絵文字の一部が含まれたとのことで、できればUnicode側のコードポイントを使いたい。 タグの開き文字・閉じ文字に工夫が必要な点も気になる。
django-bpmobileでは、DoCoMoの絵文字コードとの変換テーブルに、emoji4unicodeプロジェクトの成果を利用している。 PerlのEncode::JP::Emojiモジュールでも、同プロジェクトの変換テーブルを利用している。
emoji4unicodeプロジェクトでは、xml形式で絵文字変換テーブルを提供している。それをパースするPythonスクリプトも提供されている。 変換テーブルは以下のようなスクリプトで簡単に取り出せる。
#!/usr/bin/python from e4u import emoji4unicode as e4u_google e4u_google.Load() def describe_code(code_table, carrier): print 'carrier: %s' % carrier code_str = code_table[carrier] if code_str[0] == '>': code_str = code_str[1:] if code_str: codes = '' for code_char in code_str.split('+'): symbol = e4u_google.all_carrier_data[carrier].SymbolFromUnicode(code_char) print { 'number' : symbol.number, 'new_number': symbol.new_number, 'old_number': symbol.old_number, 'jis' : symbol.jis, 'shift_jis' : symbol.shift_jis, 'uni' : symbol.uni, 'english_name': symbol.GetEnglishName(), 'japanese_name': symbol.GetJapaneseName(), 'image_html': symbol.ImageHTML(), } return codes return '' def main(): for e in e4u_google._doc.getElementsByTagName('e'): # convert to normal dict d = {} for k, v in e.attributes.items(): d[k] = v print '*' * 40 print d for carrier in ['docomo', 'kddi', 'softbank', 'google']: if d.has_key(carrier): describe_code(d, carrier) main()
emoji4unicodeでは、Googleが内部で用いている絵文字コードとの変換表もある。この絵文字コードを採用すればいいのではないか。「Google」App Engineだし。 その場合、以下の3つが実現できればよい。 1. 各キャリアから送られる、絵文字を含んだ文字列(Shift-JIS or UTF-8)を、Googleの絵文字コードを用いたUTF-8の文字列に変換する。 2. Googleの絵文字コードを含んだUTF-8文字列を、各キャリアの絵文字コードや数値参照、タグを含んだ文字列に変換する。 3. Googleの絵文字コード、もしくは絵文字の名前を属性に持つ特殊な文字列をテンプレートに書けば、2.と同様の変換を行って表示する。
上記のスクリプトを改造して、これらの変換は実現できるだろう。PerlのEncode::JP::Emojiモジュールでも同様の変換を行い、Perlスクリプトを出力している。 Perlの場合は、trで正規表現を用いて高速に変換を行っているが、Pythonのstring.maketransはPerlのtrほど表現力はないはず。検索だけは正規表現を使うか。
Googleの絵文字コードには、現在3つの問題がある。 1. Unicodeの第15面にある私用領域(PUA)にマッピングされている。コードの範囲は、U+F0000からU+FFFFD。よって、UTF-8では4byteとなる。古いMySQLでは、保存ができない。 2. U+FEB64について、Unicode 6.0にて対応するコードポイントが2つ存在する。 3. emoji4unicodeに、willcomの絵文字との変換表がない。
1.については、MySQL 5.5.3から導入されたutf8mb4というcharsetを用いればよい。今回は、Google App Engineを用いるので、保存については問題ないだろう。 2.については、Unicode/Google絵文字コードの相互変換を行わなければさほど問題はなさそうだが、将来emoji4unicodeのマッピングが変更された場合、softbankでU+E21Aの文字列を入力した際の変換先が異なる可能性がある。なんとなくやだなー。 3.については、自らマッピングを作成するしかないだろう。
結局は、emoji-pythonライブラリで使われている、キャリア名+絵文字番号という表現形式を、1対1でUnicodeの私用領域に収めるのがいいという印象。 Unicode 6.0ですべての絵文字が採択されれば、似たような絵文字がまとめられるのもよかったかもしれないけど。 んでも、emoji-pythonもwillcomの絵文字マッピングはないのね。
絵文字対応したいという気持ちがだんだん萎えてきた!うおおお←いまここ