html2email 0.1.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.
Files changed (38) hide show
  1. data/.gitignore +1 -0
  2. data/LICENSE +23 -0
  3. data/README.markdown +110 -0
  4. data/Rakefile +57 -0
  5. data/bin/html2email +5 -0
  6. data/html2email.gemspec +47 -0
  7. data/lib/html2email/context.rb +42 -0
  8. data/lib/html2email/html_email.rb +59 -0
  9. data/lib/html2email/html_mailer.rb +49 -0
  10. data/lib/html2email/vendor/premailer/.gitignore +1 -0
  11. data/lib/html2email/vendor/premailer/CHANGELOG.rdoc +62 -0
  12. data/lib/html2email/vendor/premailer/LICENSE.rdoc +42 -0
  13. data/lib/html2email/vendor/premailer/README.rdoc +66 -0
  14. data/lib/html2email/vendor/premailer/bin/premailer +72 -0
  15. data/lib/html2email/vendor/premailer/bin/trollop.rb +739 -0
  16. data/lib/html2email/vendor/premailer/init.rb +1 -0
  17. data/lib/html2email/vendor/premailer/lib/premailer/html_to_plain_text.rb +81 -0
  18. data/lib/html2email/vendor/premailer/lib/premailer/premailer.rb +464 -0
  19. data/lib/html2email/vendor/premailer/lib/premailer.rb +9 -0
  20. data/lib/html2email/vendor/premailer/misc/client_support.yaml +230 -0
  21. data/lib/html2email/vendor/premailer/premailer.gemspec +20 -0
  22. data/lib/html2email/vendor/premailer/rakefile.rb +42 -0
  23. data/lib/html2email/vendor/premailer/tests/files/base.html +145 -0
  24. data/lib/html2email/vendor/premailer/tests/files/contact_bg.png +0 -0
  25. data/lib/html2email/vendor/premailer/tests/files/dialect.png +0 -0
  26. data/lib/html2email/vendor/premailer/tests/files/dots_end.png +0 -0
  27. data/lib/html2email/vendor/premailer/tests/files/dots_h.gif +0 -0
  28. data/lib/html2email/vendor/premailer/tests/files/import.css +13 -0
  29. data/lib/html2email/vendor/premailer/tests/files/inc/2009-placeholder.png +0 -0
  30. data/lib/html2email/vendor/premailer/tests/files/noimport.css +13 -0
  31. data/lib/html2email/vendor/premailer/tests/files/styles.css +102 -0
  32. data/lib/html2email/vendor/premailer/tests/test_helper.rb +2 -0
  33. data/lib/html2email/vendor/premailer/tests/test_html_to_plain_text.rb +73 -0
  34. data/lib/html2email/vendor/premailer/tests/test_link_resolver.rb +49 -0
  35. data/lib/html2email/vendor/premailer/tests/test_premailer.rb +124 -0
  36. data/lib/html2email.rb +110 -0
  37. data/spec/html2email.spec.rb +9 -0
  38. metadata +176 -0
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class TestLinkResolver < Test::Unit::TestCase
4
+ def test_resolving_urls_from_string
5
+ ['test.html', '/test.html', './test.html',
6
+ 'test/../test.html', 'test/../test/../test.html'].each do |q|
7
+ assert_equal 'http://example.com/test.html', Premailer.resolve_link(q, 'http://example.com/'), q
8
+ end
9
+
10
+ assert_equal 'https://example.net:80/~basedir/test.html?var=1#anchor', Premailer.resolve_link('test/../test/../test.html?var=1#anchor', 'https://example.net:80/~basedir/')
11
+ end
12
+
13
+ def test_resolving_urls_from_uri
14
+ base_uri = URI.parse('http://example.com/')
15
+ ['test.html', '/test.html', './test.html',
16
+ 'test/../test.html', 'test/../test/../test.html'].each do |q|
17
+ assert_equal 'http://example.com/test.html', Premailer.resolve_link(q, base_uri), q
18
+ end
19
+
20
+ base_uri = URI.parse('https://example.net:80/~basedir/')
21
+ assert_equal 'https://example.net:80/~basedir/test.html?var=1#anchor', Premailer.resolve_link('test/../test/../test.html?var=1#anchor', base_uri)
22
+
23
+ # base URI with a query string
24
+ base_uri = URI.parse('http://example.com/dir/index.cfm?newsletterID=16')
25
+ assert_equal 'http://example.com/dir/index.cfm?link=15', Premailer.resolve_link('?link=15', base_uri)
26
+
27
+ # URI preceded by a space
28
+ base_uri = URI.parse('http://example.com/')
29
+ assert_equal 'http://example.com/path', Premailer.resolve_link(' path', base_uri)
30
+ end
31
+
32
+ def test_resolving_urls_in_doc
33
+ base_file = File.dirname(__FILE__) + '/files/base.html'
34
+ base_url = 'https://my.example.com:8080/test-path.html'
35
+ premailer = Premailer.new(base_file, :base_url => base_url)
36
+ premailer.to_inline_css
37
+ pdoc = premailer.processed_doc
38
+ doc = premailer.doc
39
+
40
+ # unchanged links
41
+ ['#l02', '#l03', '#l05', '#l06', '#l07', '#l08',
42
+ '#l09', '#l10', '#l11', '#l12', '#l13'].each do |link_id|
43
+ assert_equal doc.at(link_id).attributes['href'], pdoc.at(link_id).attributes['href'], link_id
44
+ end
45
+
46
+ assert_equal 'https://my.example.com:8080/', pdoc.at('#l01').attributes['href']
47
+ assert_equal 'https://my.example.com:8080/images/', pdoc.at('#l04').attributes['href']
48
+ end
49
+ end
@@ -0,0 +1,124 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'webrick'
3
+
4
+ class TestPremailer < Test::Unit::TestCase
5
+ include WEBrick
6
+
7
+ def test_accents
8
+ local_setup
9
+
10
+ assert_equal 'cédille c&eacute; garçon gar&#231;on à &agrave;', @doc.at('#accents').inner_html
11
+ end
12
+
13
+ def test_escaping_strings
14
+ local_setup
15
+
16
+ str = %q{url("/images/test.png");}
17
+ assert_equal("url(\'/images/test.png\');", Premailer.escape_string(str))
18
+ end
19
+
20
+ def test_importing_local_css
21
+ flunk
22
+ local_setup
23
+
24
+ # noimport.css (print stylesheet) sets body { background } to red
25
+ assert_no_match /red/, @doc.at('body').attributes['style']
26
+
27
+ # import.css sets .hide to { display: none }
28
+ assert_match /display: none/, @doc.at('#hide01').attributes['style']
29
+ end
30
+
31
+ def test_importing_remote_css
32
+ flunk
33
+ remote_setup
34
+
35
+ # noimport.css (print stylesheet) sets body { background } to red
36
+ assert_no_match /red/, @doc.at('body').attributes['style']
37
+
38
+ # import.css sets .hide to { display: none }
39
+ assert_match /display: none/, @doc.at('#hide01').attributes['style']
40
+ end
41
+
42
+
43
+ def test_related_attributes
44
+ local_setup
45
+
46
+ # h1 { text-align: center; }
47
+ assert_equal 'center', @doc.at('h1')['align']
48
+
49
+ # td { vertical-align: top; }
50
+ assert_equal 'top', @doc.at('td')['valign']
51
+
52
+ # p { vertical-align: top; } -- not allowed
53
+ assert_nil @doc.at('p')['valign']
54
+
55
+ # no align attr is specified for <p> elements, so it should not appear
56
+ assert_nil @doc.at('p.unaligned')['align']
57
+
58
+ # .contact { background: #9EC03B url("contact_bg.png") repeat 0 0; }
59
+ assert_equal '#9EC03B', @doc.at('td.contact')['bgcolor']
60
+
61
+ # body { background-color: #9EBF00; }
62
+ assert_equal '#9EBF00', @doc.at('body')['bgcolor']
63
+ end
64
+
65
+ def test_merging_cellpadding
66
+ flunk
67
+ local_setup('cellpadding.html', {:prefer_cellpadding => true})
68
+ assert_equal '0', @doc.at('#t1')['cellpadding']
69
+ assert_match /padding\:/i, @doc.at('#t1 td')['style']
70
+
71
+ assert_equal '5', @doc.at('#t2')['cellpadding']
72
+ assert_no_match /padding\:/i, @doc.at('#t2 td')['style']
73
+
74
+ assert_nil @doc.at('#t3')['cellpadding']
75
+ assert_match /padding\:/i, @doc.at('#t3 td')['style']
76
+
77
+ assert_nil @doc.at('#t4')['cellpadding']
78
+ assert_match /padding\:/i, @doc.at('#t4a')['style']
79
+ assert_match /padding\:/i, @doc.at('#t4b')['style']
80
+ end
81
+
82
+ def test_preserving_media_queries
83
+ local_setup
84
+ assert_match /display\: none/i, @doc.at('#iphone')['style']
85
+ end
86
+
87
+ protected
88
+ def local_setup(f = 'base.html', opts = {})
89
+ base_file = File.dirname(__FILE__) + '/files/' + f
90
+ premailer = Premailer.new(base_file, opts)
91
+ premailer.to_inline_css
92
+ @doc = premailer.processed_doc
93
+ end
94
+
95
+ def remote_setup(opts = {})
96
+ # from http://nullref.se/blog/2006/5/17/testing-with-webrick
97
+ uri_base = 'http://localhost:12000'
98
+ www_root = File.dirname(__FILE__) + '/files/'
99
+
100
+ @server_thread = Thread.new do
101
+ s = WEBrick::HTTPServer.new(:Port => 12000, :DocumentRoot => www_root, :Logger => Log.new(nil, BasicLog::ERROR), :AccessLog => [])
102
+ port = s.config[:Port]
103
+ begin
104
+ s.start
105
+ ensure
106
+ s.shutdown
107
+ end
108
+ end
109
+
110
+ sleep 1 # ensure the server has time to load
111
+
112
+ premailer = Premailer.new(uri_base + '/base.html', opts)
113
+ premailer.to_inline_css
114
+ @doc = premailer.processed_doc
115
+ end
116
+
117
+ def teardown
118
+ if @server_thread
119
+ @server_thread.kill
120
+ @server_thread.join(5)
121
+ @server_thread = nil
122
+ end
123
+ end
124
+ end
data/lib/html2email.rb ADDED
@@ -0,0 +1,110 @@
1
+ require 'optparse'
2
+ require 'fileutils'
3
+ require 'html2email/html_email'
4
+ require 'html2email/html_mailer'
5
+
6
+ #
7
+ # Command line wrapper for creating and writing HtmlEmail objects
8
+ #
9
+ class Html2Email
10
+ VERSION = '0.1.2'
11
+
12
+ def initialize(args = [])
13
+ @args, @options = args, { :default_type => 'str', :test_recipients => [] }
14
+ end
15
+
16
+ def options
17
+ OptionParser.new do |opt|
18
+ opt.banner = %Q{\
19
+ Convert an html file to an email-compatible form.
20
+
21
+ Usage: #{File.basename $0} [options] [infile[:outfile], ...]
22
+
23
+ Options:
24
+ }.gsub(/^ +/,'')
25
+
26
+ opt.on('-l', '--layout FILE', 'Use FILE as a layout template') do |arg|
27
+ @options[:layout] = File.expand_path arg
28
+ end
29
+
30
+ types = Tilt.mappings.keys
31
+ opt.on('-t', '--default-type FORMAT',
32
+ 'Fall back to FORMAT when template type cannot be inferred from',
33
+ "a file's extension, e.g. input from STDIN. " +
34
+ "Defaults to `#{@options[:default_type]}'") do |arg|
35
+ if types.include? arg
36
+ @options[:default_type] = arg
37
+ else
38
+ raise ArgumentError, "Default type must be one of: #{types.join ', '}"
39
+ end
40
+ end
41
+
42
+ opt.on('-e', '--email [ADDR,ADDR]', Array,
43
+ 'Send rendered html to recipients; list can also be defined',
44
+ 'within the template') do |arg|
45
+ @options[:email_test] = true
46
+ @options[:test_recipients] = arg || []
47
+ end
48
+
49
+ opt.on('--stdout',
50
+ 'Write to STDOUT when an outfile is not explicitly specified') do
51
+ @options[:stdout] = true
52
+ end
53
+
54
+ opt.separator "\nSupported FORMATs:\n#{types.join ', '}"
55
+ end
56
+ end
57
+
58
+ # Command line interface
59
+ def run
60
+ options.parse! @args
61
+ messages = []
62
+
63
+ process(@args).each do |infile, outfile|
64
+ htmlemail = HtmlEmail.new infile, @options[:layout], @options
65
+ write (html = htmlemail.render), outfile
66
+ messages << html
67
+ @options[:test_recipients] += htmlemail.test_recipients
68
+ end
69
+
70
+ if @options[:email_test]
71
+ HtmlMailer.new(messages, @options[:test_recipients].uniq).html_send
72
+ end
73
+ ensure
74
+ FileUtils.rm_f(@tempfile) if @tempfile
75
+ end
76
+
77
+ private
78
+
79
+ def process(list)
80
+ # read from stdin if no file args
81
+ if list.empty?
82
+ # both Tilt and Premailer expect files as inputs; so we use a tempfile
83
+ @tempfile = Tempfile.new [self.class.to_s, '.' + @options[:default_type]]
84
+ @tempfile.write $stdin.read; @tempfile.rewind
85
+ [[@tempfile.path, $stdout]]
86
+ else
87
+ list.map { |a| a.split ':', 2 }.map do |i,o|
88
+ out = if o.nil? || o.empty?
89
+ if @options[:stdout]
90
+ $stdout
91
+ else
92
+ File.expand_path(i[/.html$/] ? i : i.chomp(File.extname i))
93
+ end
94
+ else
95
+ File.expand_path o
96
+ end
97
+ [File.expand_path(i), out]
98
+ end
99
+ end
100
+ end
101
+
102
+ def write(string, dst)
103
+ if dst.kind_of? IO
104
+ dst.write string
105
+ else
106
+ warn "# Writing #{dst}"
107
+ File.open(dst, 'w') { |f| f.write string }
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path '../../lib/html2email', __FILE__
2
+
3
+ describe Html2Email do
4
+ describe :VERSION do
5
+ it 'should contain the version string' do
6
+ Html2Email::VERSION.should =~ /^\d+\.\d+\.\d+$/
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: html2email
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 2
9
+ version: 0.1.2
10
+ platform: ruby
11
+ authors:
12
+ - guns
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-24 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rack
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: tilt
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :runtime
43
+ version_requirements: *id002
44
+ - !ruby/object:Gem::Dependency
45
+ name: hpricot
46
+ prerelease: false
47
+ requirement: &id003 !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ - 6
54
+ version: "0.6"
55
+ type: :runtime
56
+ version_requirements: *id003
57
+ - !ruby/object:Gem::Dependency
58
+ name: css_parser
59
+ prerelease: false
60
+ requirement: &id004 !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ - 9
67
+ - 1
68
+ version: 0.9.1
69
+ type: :runtime
70
+ version_requirements: *id004
71
+ - !ruby/object:Gem::Dependency
72
+ name: text-reform
73
+ prerelease: false
74
+ requirement: &id005 !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ segments:
79
+ - 0
80
+ - 2
81
+ - 0
82
+ version: 0.2.0
83
+ type: :runtime
84
+ version_requirements: *id005
85
+ - !ruby/object:Gem::Dependency
86
+ name: htmlentities
87
+ prerelease: false
88
+ requirement: &id006 !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ segments:
93
+ - 4
94
+ - 0
95
+ - 0
96
+ version: 4.0.0
97
+ type: :runtime
98
+ version_requirements: *id006
99
+ description: Convert ruby html templates to an email compatible form.
100
+ email: sung@metablu.com
101
+ executables:
102
+ - html2email
103
+ extensions: []
104
+
105
+ extra_rdoc_files: []
106
+
107
+ files:
108
+ - .gitignore
109
+ - LICENSE
110
+ - README.markdown
111
+ - Rakefile
112
+ - bin/html2email
113
+ - html2email.gemspec
114
+ - lib/html2email.rb
115
+ - lib/html2email/context.rb
116
+ - lib/html2email/html_email.rb
117
+ - lib/html2email/html_mailer.rb
118
+ - spec/html2email.spec.rb
119
+ - lib/html2email/vendor/premailer/.gitignore
120
+ - lib/html2email/vendor/premailer/CHANGELOG.rdoc
121
+ - lib/html2email/vendor/premailer/LICENSE.rdoc
122
+ - lib/html2email/vendor/premailer/README.rdoc
123
+ - lib/html2email/vendor/premailer/bin/premailer
124
+ - lib/html2email/vendor/premailer/bin/trollop.rb
125
+ - lib/html2email/vendor/premailer/init.rb
126
+ - lib/html2email/vendor/premailer/lib/premailer.rb
127
+ - lib/html2email/vendor/premailer/lib/premailer/html_to_plain_text.rb
128
+ - lib/html2email/vendor/premailer/lib/premailer/premailer.rb
129
+ - lib/html2email/vendor/premailer/misc/client_support.yaml
130
+ - lib/html2email/vendor/premailer/premailer.gemspec
131
+ - lib/html2email/vendor/premailer/rakefile.rb
132
+ - lib/html2email/vendor/premailer/tests/files/base.html
133
+ - lib/html2email/vendor/premailer/tests/files/contact_bg.png
134
+ - lib/html2email/vendor/premailer/tests/files/dialect.png
135
+ - lib/html2email/vendor/premailer/tests/files/dots_end.png
136
+ - lib/html2email/vendor/premailer/tests/files/dots_h.gif
137
+ - lib/html2email/vendor/premailer/tests/files/import.css
138
+ - lib/html2email/vendor/premailer/tests/files/inc/2009-placeholder.png
139
+ - lib/html2email/vendor/premailer/tests/files/noimport.css
140
+ - lib/html2email/vendor/premailer/tests/files/styles.css
141
+ - lib/html2email/vendor/premailer/tests/test_helper.rb
142
+ - lib/html2email/vendor/premailer/tests/test_html_to_plain_text.rb
143
+ - lib/html2email/vendor/premailer/tests/test_link_resolver.rb
144
+ - lib/html2email/vendor/premailer/tests/test_premailer.rb
145
+ has_rdoc: true
146
+ homepage: http://github.com/guns/html2email
147
+ licenses: []
148
+
149
+ post_install_message:
150
+ rdoc_options: []
151
+
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ segments:
159
+ - 0
160
+ version: "0"
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ segments:
166
+ - 0
167
+ version: "0"
168
+ requirements: []
169
+
170
+ rubyforge_project:
171
+ rubygems_version: 1.3.6
172
+ signing_key:
173
+ specification_version: 3
174
+ summary: "Html2Email: Tilt + Premailer + SMTP"
175
+ test_files: []
176
+