staugaard-idn_actionmailer 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +6 -0
- data/README.txt +9 -0
- data/Rakefile +17 -0
- data/idn_actionmailer.gemspec +18 -0
- data/lib/idn_actionmailer.rb +69 -0
- data/test/fixtures/test_mailer/signed_up_with_url.erb +1 -0
- data/test/fixtures/test_mailer/signed_up_with_url.rhtml +0 -0
- data/test/test_encoding.rb +24 -0
- data/test/test_idn_actionmailer.rb +83 -0
- metadata +88 -0
data/History.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
= IdnActionmailer
|
2
|
+
|
3
|
+
idn_actionmailer is a gem that patches actionmailer to support recipients on domains with international characters.
|
4
|
+
|
5
|
+
This is done by encoding these domain names.
|
6
|
+
|
7
|
+
To use this gem in your rails project just install it and and " require 'idn_actionmailer' " to the bottom of your environment.rb.
|
8
|
+
|
9
|
+
I KNOW NOTHING ABOUT HOW THE ENCODING WORKS. I just patched the actionmailer code.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/idn_actionmailer.rb'
|
6
|
+
|
7
|
+
Hoe.new('IdnActionmailer', IdnActionmailer::VERSION) do |p|
|
8
|
+
p.author = 'Mick Staugaard'
|
9
|
+
p.email = 'mick@staugaard.com'
|
10
|
+
p.summary = 'monkey patch for ActionMailer to support international domain names'
|
11
|
+
p.description = 'monkey patch for ActionMailer to support international domain names'
|
12
|
+
p.url = 'http://github.com/staugaard/idn_actionmailer'
|
13
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
14
|
+
#p.extra_deps << ['mime-types']
|
15
|
+
end
|
16
|
+
|
17
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "idn_actionmailer"
|
3
|
+
s.version = "0.2"
|
4
|
+
s.date = "2008-05-27"
|
5
|
+
s.summary = "monkey patch for ActionMailer to support international domain names"
|
6
|
+
s.email = "mick@staugaard.com"
|
7
|
+
s.homepage = "http://github.com/staugaard/idn_actionmailer"
|
8
|
+
s.description = "monkey patch for ActionMailer to support international domain names"
|
9
|
+
s.has_rdoc = false
|
10
|
+
s.authors = ["Mick Staugaard"]
|
11
|
+
s.files = ["History.txt", "README.txt", "Rakefile", "idn_actionmailer.gemspec", "lib/idn_actionmailer.rb"]
|
12
|
+
s.test_files = ["test/test_encoding.rb", "test/test_idn_actionmailer.rb", "test/fixtures/test_mailer/signed_up_with_url.erb", "test/fixtures/test_mailer/signed_up_with_url.rhtml"]
|
13
|
+
s.rdoc_options = ["--main", "README.txt"]
|
14
|
+
s.extra_rdoc_files = ["History.txt", "README.txt"]
|
15
|
+
s.add_dependency("actionmailer", [">= 2.0.2"])
|
16
|
+
s.add_dependency("unicode", [">= 0.1"])
|
17
|
+
s.add_dependency("punycode4r", [">= 0.2.0"])
|
18
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'unicode'
|
3
|
+
require 'punycode'
|
4
|
+
require 'actionmailer'
|
5
|
+
|
6
|
+
class IdnActionmailer
|
7
|
+
VERSION = '0.2'
|
8
|
+
|
9
|
+
UTF8REGEX = /\A(?:
|
10
|
+
[\x09\x0A\x0D\x20-\x7E] # ASCII
|
11
|
+
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
12
|
+
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
13
|
+
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
14
|
+
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
15
|
+
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
16
|
+
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
|
17
|
+
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
18
|
+
)*\z/mnx
|
19
|
+
|
20
|
+
|
21
|
+
UTF8_REGEX_MBYTE = /(?:
|
22
|
+
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
23
|
+
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
24
|
+
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
25
|
+
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
26
|
+
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
27
|
+
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
|
28
|
+
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
29
|
+
)/mnx
|
30
|
+
|
31
|
+
def self.encode(str)
|
32
|
+
if str =~ UTF8REGEX && str =~ UTF8_REGEX_MBYTE
|
33
|
+
|
34
|
+
parts = Unicode::downcase(str).split('.')
|
35
|
+
parts.map! do |part|
|
36
|
+
if part =~ UTF8REGEX && part =~ UTF8_REGEX_MBYTE
|
37
|
+
"xn--" + Punycode.encode(Unicode::normalize_KC(part))
|
38
|
+
else
|
39
|
+
part
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
parts.join('.')
|
44
|
+
else
|
45
|
+
str
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module ActionMailer
|
51
|
+
module Quoting
|
52
|
+
alias_method :orig_quote_address_if_necessary, :quote_address_if_necessary
|
53
|
+
|
54
|
+
def quote_address_if_necessary(address, charset)
|
55
|
+
if Array === address
|
56
|
+
orig_quote_address_if_necessary(address, charset)
|
57
|
+
else
|
58
|
+
if(address =~ /^(.*(<)?.*@)(.*)(>)?$/)
|
59
|
+
predomain = $1
|
60
|
+
domain = IdnActionmailer.encode($3)
|
61
|
+
postdomain = $4
|
62
|
+
orig_quote_address_if_necessary("#{predomain}#{domain}#{postdomain}", charset)
|
63
|
+
else
|
64
|
+
orig_quote_address_if_necessary(address, charset)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello there
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
|
3
|
+
require "idn_actionmailer"
|
4
|
+
|
5
|
+
class EncodingTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@domains = [['مثال.إختبار', 'xn--mgbh0fb.xn--kgbechtv'],
|
8
|
+
['例子.测试', 'xn--fsqu00a.xn--0zwm56d'],
|
9
|
+
['例子.測試', 'xn--fsqu00a.xn--g6w251d'],
|
10
|
+
['παράδειγμα.δοκιμή', 'xn--hxajbheg2az3al.xn--jxalpdlp'],
|
11
|
+
['उदाहरण.परीक्षा', 'xn--p1b6ci4b4b3a.xn--11b5bs3a9aj6g'],
|
12
|
+
['例え.テスト', 'xn--r8jz45g.xn--zckzah'],
|
13
|
+
['실례.테스트', 'xn--9n2bp8q.xn--9t4b11yi5a'],
|
14
|
+
['пример.испытание', 'xn--e1afmkfd.xn--80akhbyknj4f'],
|
15
|
+
['உதாரணம்.பரிட்சை', 'xn--zkc6cc5bi7f6e.xn--hlcj6aya9esc7a'],
|
16
|
+
['blåbærgrød.dk', 'xn--blbrgrd-fxak7p.dk']]
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_encoding
|
20
|
+
@domains.each do |pair|
|
21
|
+
assert_equal(pair[1], IdnActionmailer.encode(pair[0]))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
|
3
|
+
require "idn_actionmailer"
|
4
|
+
|
5
|
+
ActionMailer::Base.template_root = "#{File.dirname(__FILE__)}/fixtures"
|
6
|
+
|
7
|
+
class TestMailer < ActionMailer::Base
|
8
|
+
|
9
|
+
default_url_options[:host] = 'www.basecamphq.com'
|
10
|
+
|
11
|
+
def signed_up_with_url(recipient)
|
12
|
+
@recipients = recipient
|
13
|
+
@subject = "[Signed up] Welcome"
|
14
|
+
@from = "bla <system@loudthinking.com>"
|
15
|
+
@sent_on = Time.local(2004, 12, 12)
|
16
|
+
|
17
|
+
@body["recipient"] = recipient
|
18
|
+
end
|
19
|
+
|
20
|
+
class <<self
|
21
|
+
attr_accessor :received_body
|
22
|
+
end
|
23
|
+
|
24
|
+
def receive(mail)
|
25
|
+
self.class.received_body = mail.body
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class ActionMailerUrlTest < Test::Unit::TestCase
|
30
|
+
include ActionMailer::Quoting
|
31
|
+
|
32
|
+
def encode( text, charset="utf-8" )
|
33
|
+
quoted_printable( text, charset )
|
34
|
+
end
|
35
|
+
|
36
|
+
def new_mail( charset="utf-8" )
|
37
|
+
mail = TMail::Mail.new
|
38
|
+
mail.mime_version = "1.0"
|
39
|
+
if charset
|
40
|
+
mail.set_content_type "text", "plain", { "charset" => charset }
|
41
|
+
end
|
42
|
+
mail
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup
|
46
|
+
ActionMailer::Base.delivery_method = :test
|
47
|
+
ActionMailer::Base.perform_deliveries = true
|
48
|
+
ActionMailer::Base.deliveries = []
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_single_address
|
52
|
+
|
53
|
+
expected = new_mail
|
54
|
+
expected.to = 'bla <mick@xn--brndendekrlighed-vobh.dk>'
|
55
|
+
expected.subject = "[Signed up] Welcome"
|
56
|
+
expected.body = "Hello there"
|
57
|
+
expected.from = "bla <system@loudthinking.com>"
|
58
|
+
expected.date = Time.local(2004, 12, 12)
|
59
|
+
|
60
|
+
created = nil
|
61
|
+
assert_nothing_raised { created = TestMailer.create_signed_up_with_url('bla <mick@brændendekærlighed.dk>') }
|
62
|
+
assert_not_nil created
|
63
|
+
assert_equal expected.encoded, created.encoded
|
64
|
+
|
65
|
+
assert_nothing_raised { TestMailer.deliver_signed_up_with_url('bla <mick@brændendekærlighed.dk>') }
|
66
|
+
assert_not_nil ActionMailer::Base.deliveries.first
|
67
|
+
assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_multi_addresses
|
71
|
+
expected = new_mail
|
72
|
+
expected.to = ['bla <mick@xn--brndendekrlighed-vobh.dk>', 'mick@xn--brndendekrlighed-vobh.dk']
|
73
|
+
expected.subject = "[Signed up] Welcome"
|
74
|
+
expected.body = "Hello there"
|
75
|
+
expected.from = "bla <system@loudthinking.com>"
|
76
|
+
expected.date = Time.local(2004, 12, 12)
|
77
|
+
|
78
|
+
created = nil
|
79
|
+
assert_nothing_raised { created = TestMailer.create_signed_up_with_url(['bla <mick@brændendekærlighed.dk>', 'mick@brændendekærlighed.dk']) }
|
80
|
+
assert_not_nil created
|
81
|
+
assert_equal expected.encoded, created.encoded
|
82
|
+
end
|
83
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: staugaard-idn_actionmailer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.2"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mick Staugaard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-05-27 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: actionmailer
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.2
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: unicode
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: "0.1"
|
32
|
+
version:
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: punycode4r
|
35
|
+
version_requirement:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.2.0
|
41
|
+
version:
|
42
|
+
description: monkey patch for ActionMailer to support international domain names
|
43
|
+
email: mick@staugaard.com
|
44
|
+
executables: []
|
45
|
+
|
46
|
+
extensions: []
|
47
|
+
|
48
|
+
extra_rdoc_files:
|
49
|
+
- History.txt
|
50
|
+
- README.txt
|
51
|
+
files:
|
52
|
+
- History.txt
|
53
|
+
- README.txt
|
54
|
+
- Rakefile
|
55
|
+
- idn_actionmailer.gemspec
|
56
|
+
- lib/idn_actionmailer.rb
|
57
|
+
has_rdoc: false
|
58
|
+
homepage: http://github.com/staugaard/idn_actionmailer
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --main
|
62
|
+
- README.txt
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.0.1
|
81
|
+
signing_key:
|
82
|
+
specification_version: 2
|
83
|
+
summary: monkey patch for ActionMailer to support international domain names
|
84
|
+
test_files:
|
85
|
+
- test/test_encoding.rb
|
86
|
+
- test/test_idn_actionmailer.rb
|
87
|
+
- test/fixtures/test_mailer/signed_up_with_url.erb
|
88
|
+
- test/fixtures/test_mailer/signed_up_with_url.rhtml
|