1

mailman gem (メールも使用) を使用して外部サーバーから電子メールを読み取るアプリに問題があります。

ruby 1.9.2p0
mail (2.3.0)
mailman (0.4.0) 
actionmailer (= 3.1.3)

データベース.yml

production:
  adapter: mysql2
  encoding: utf8

「メール」を受信する簡単な方法を次に示します。マルチパート電子メールの text_part (添付ファイル付きなど) または本文全体 (デコード済み) から @message_body を作成します。

def self.receive_mail(message)
    # some code here 
    @message_body = message.multipart? ? message.text_part.body.to_s : message.body.decoded
    # some code here, to save message in database

私の問題は、メッセージに添付ファイルがなく、 ą ś ł ń ż ź ó のような分音記号がある場合、最初の分音記号の直前で本文が分割されることです。したがって、本文が「test żłóbek test」の場合、@message_body には「test」のみが表示されます。

私の質問は、そのようなメッセージをエレガントな方法で保存する方法です。これにより、テキスト部分がすべての分音記号とともにデータベースに保存されます。

編集: わかりやすくするために、次のような電子メールが届きます (gmail から送信された電子メールの一部にすぎません)。

--20cf307ac4372d830104c11c8cc6 日付: 2012 年 5 月 28 日月曜日 20:06:16 +0200 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-2 Content-Transfer-Encoding: base64 Content-ID: <4fc3be989b76e_794650c25f6625e3@vk1057.some_domain>

dGVzdCC/s7zm8bbzsSB0ZXN0Cg==

したがって、この「本体」があります: dGVzdCC/s7zm8bbzsSB0ZXN0Cg==

デコード後、次のようになります: 'test \xbf\xb3\xbc\xe6\xf1\xb6\xf3\xb1 test\n'

そして問題は、「\xbf」から始まるデータがデータベースに保存されないことです。

アップデート

別の例ですが、これが問題だと思います:

irb(main):008:0* require 'base64'
=> true
irb(main):009:0> a = "test źćłżąńś"
=> "test źćłżąńś"
irb(main):010:0> b = Base64.encode64(a)
=> "dGVzdCDFusSHxYLFvMSFxYTFmw==\n"
irb(main):011:0> Base64.decode64(b)
=> "test \xC5\xBA\xC4\x87\xC5\x82\xC5\xBC\xC4\x85\xC5\x84\xC5\x9B"

ほら、decode64 の後、分音符号が失われました。それらを元に戻すにはどうすればよいですか?

4

2 に答える 2

1
force_encoding('utf-8')

データが utf-8 ではないため、機能しません。メール ヘッダーには、メッセージ本文が ISO 8859-2 であることが明確に示されています。

Mysql2 はすべてが utf8 であると想定していますが、バイトを utf8 に変換することはできません (Ruby は元のエンコーディングを認識していないため)。したがって、ASCII 以外の文字は mysql によって破棄されます。

その1つの文字列について、試すことができます

body.force_encoding('ISO-8859-2').encode('utf-8')

しかし、実際には、コンテンツ タイプ ヘッダーからどのエンコーディングを使用するかを検討する必要があります。メールジェムがあなたのためにそれをしていないことに驚いています

于 2012-05-28T20:18:12.217 に答える
0

私には解決策があります。の連結

.force_encoding("ORIGINAL_CHARSET").encode("UTF-8")

電子メール本文オブジェクトのメソッドが解決策です。

receive_mail()以前の「ワンライナー」から次のように定義を変更する必要がありました。

if message.multipart?
    charset = message.text_part.content_type_parameters[:charset]
    @message_body = message.text_part.body.to_s.force_encoding(charset).encode("UTF-8")
else
    charset = message.content_type_parameters[:charset]
    @message_body = message.body.decoded.force_encoding(charset).encode("UTF-8")
end

この構成を使用すると、元の電子メールの文字セットを検出し、それを強制してUTF-8にエンコードして戻すことができます。これにより、base64からオリジナルからutf-8への適切なデコードが保証されます。

誰かがよりエレガントな解決策を持っているなら、共有してください。

于 2012-05-28T20:22:57.670 に答える