2012-06-14 4 views
9

Sto cercando di analizzare le stringhe di posta elettronica con lo Ruby mail gem e sto avendo un diavolo di tempo con le codifiche dei caratteri. Prendere la seguente email:Codifica dei caratteri con Ruby 1.9.3 e la gemma della posta

MIME-Version: 1.0 
Sender: [email protected] 
Received: by 10.142.239.17 with HTTP; Thu, 14 Jun 2012 06:00:18 -0700 (PDT) 
Date: Thu, 14 Jun 2012 09:00:18 -0400 
Delivered-To: [email protected] 
X-Google-Sender-Auth: MxfFrMybNjBoBt4O4GwAn9cMsko 
Message-ID: <[email protected]om> 
Subject: Re: [Lorem Ipsum] Foo updated the forum topic 'Reply by email test' 
From: Foo Bar <[email protected]> 
To: Foo <[email protected]> 
Content-Type: text/plain; charset=ISO-8859-1 
Content-Transfer-Encoding: quoted-printable 

This email has accents:=A0R=E9sum=E9 
> 
> --------- Reply Above This Line ------------ 
> 
> Email parsing with accents: R=E9sum=E9 
> 
> Click here to view this post in your browser 

Il corpo dell'e-mail, se correttamente codificato, dovrebbe essere:

This reply has accents: Résumé 
> 
> --------- Reply Above This Line ------------ 
> 
> Email parsing with accents: Résumé 
> 
> Click here to view this post in your browser 

Tuttavia, sto avendo un diavolo di un tempo effettivamente ottenere i accenti a venire attraverso. Ecco quello che ho provato:

message = Mail.new(email_string) 
body = message.body.decoded 

Questo mi ottiene una stringa che inizia in questo modo:

This reply has accents:\xA0R\xE9sum\xE9\r\n>\r\n> --------- Reply Above This Line ------------ 

Infine, provo questo:

body.encoding # => <Encoding:ASCII-8BIT> 
body.encode("UTF-8") # => Encoding::UndefinedConversionError: "\xA0" from ASCII-8BIT to UTF-8 

Qualcuno ha qualche suggerimento su come affrontare questo? Sono abbastanza sicuro che abbia a che fare con l'impostazione "charset = ISO-8859-1" nell'e-mail, ma non sono sicuro di come usarlo, o se c'è un modo per estrarlo facilmente usando la gemma della posta.

risposta

17

Dopo aver giocato un po ', ho trovato questo:

body.decoded.force_encoding("ISO-8859-1").encode("UTF-8") # => "This reply has accents: Résumé..." 
message.parts.map { |part| part.decoded.force_encoding("ISO-8859-1").encode(part.charset) } # multi-part 

È possibile estrarre il set di caratteri dal messaggio in questo modo.

message.charset #=> for simple, non-multipart 
message.parts.map { |part| part.charset } #=> for multipart, each part can have its own charset 

stare attenti con non più parti, come la seguente può causare problemi:

body.charset #=> returns "US-ASCII" which is WRONG! 
body.force_encoding(body.charset).encode("UTF-8") #=> Conversion error... 

body.force_encoding(message.charset).encode("UTF-8") #=> Correct conversion :) 
+1

Impressionante. State cercando questo. Terminato facendo questo: body = message.text_part.encode ('UTF-8', message.text_part.charset,: invalid =>: replace,: undef =>: replace) –

+0

Impressionante ...... Grazie a tun ... – Jyothu

+0

Alcune parti sembrano avere un set di caratteri nullo. Non sono ancora sicuro di come gestirli. –

0

Questo non ha funzionato per me, così ho pensato di bastone la soluzione che ho avuto modo nel caso in cui aiuta chiunque ...

Fondamentalmente è stato necessario aggiungere le impostazioni di codifica predefinite e ottimizzare l'output in stringhe sensate. https://stackoverflow.com/a/26604049/2386548