eml_to_pdf 0.2.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e81efeb010801805fe22e63ff844e4a3f400955c
4
- data.tar.gz: 1a02a94a289f960e79827c5f63d927d6d37a2888
2
+ SHA256:
3
+ metadata.gz: 4ca4521f1d3dd67c4bec67daa9470390d9fb4f2ea6567e2623241699f812a9c2
4
+ data.tar.gz: beaaf4003bd695c8621e6a81e4afa66c0bb829a0d0d5fa582ca18815e5e93697
5
5
  SHA512:
6
- metadata.gz: b613139c02acf27408c43fad2114e34db2321ea9fa2b3709923f4dbc610d15f62751bce105a06e046b7d7246487b6e46d59a785fbe0afc84efe47decb1b70e8c
7
- data.tar.gz: 43e6e8b27008a6482229fa8077af78bcc245b0987d905c3fb7636b3de4f387308a9a459aa6413f05bd3df2df000580fa26583622a195808dc7f74a558bdc76cc
6
+ metadata.gz: 404e1d85c233b1fb6a8b753a755210b76f8e3cfa571e0fe3ee8b205d83c0d4bf1f5879f31b30f340133ef94057aa4e67af548c10f67e2a1a7a8627c20a3f3505
7
+ data.tar.gz: 0c8a0d071dad60ce8bfaf43c5b0d33c1250902aa0e032de0f107d8cf7d7996b34c942bd7682b127b4576ecb85b34afc9eccdcd72babdf05facc1748c09cf4bd8
@@ -0,0 +1,5 @@
1
+ languages:
2
+ Ruby: true
3
+ exclude_paths:
4
+ - "lib/eml_to_pdf/extraction_step.rb"
5
+ - "test/"
data/.gitignore CHANGED
@@ -6,4 +6,5 @@
6
6
  /doc/
7
7
  /pkg/
8
8
  /spec/reports/
9
- /tmp/
9
+ /tmp/*
10
+ !/tmp/.gitkeep
@@ -1 +1 @@
1
- 2.2.2
1
+ 2.7.1
@@ -1,4 +1,11 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
- - 2.2.2
4
- before_install: gem install bundler -v 1.10.6
4
+ - 2.6
5
+ - 2.7
6
+
7
+ before_install:
8
+ - gem install bundler
9
+ - sudo apt-get install xfonts-75dpi xfonts-base
10
+ - wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.xenial_amd64.deb
11
+ - sudo apt install ./wkhtmltox_0.12.5-1.xenial_amd64.deb
data/README.md CHANGED
@@ -4,7 +4,8 @@ Welcome to EmlToPdf.
4
4
  A small converter to convert an eml file to a pdf.
5
5
  This gem uses `wkhtmltopdf`. You can get the installer from [here](http://wkhtmltopdf.org/downloads.html)
6
6
 
7
- [![Build Status](https://travis-ci.org/Elektron1c97/eml_to_pdf.svg?branch=master)](https://travis-ci.org/Elektron1c97/eml_to_pdf)
7
+ [![Build Status](https://travis-ci.org/siegy22/eml_to_pdf.svg?branch=master)](https://travis-ci.org/siegy22/eml_to_pdf)
8
+ [![Code Climate](https://codeclimate.com/github/siegy22/eml_to_pdf/badges/gpa.svg)](https://codeclimate.com/github/siegy22/eml_to_pdf)
8
9
 
9
10
  ## Installation
10
11
 
@@ -30,11 +31,14 @@ Use the `configure` method to configure your labels
30
31
 
31
32
  ```ruby
32
33
  EmlToPdf.configure do |config|
34
+ config.timeout = 60 # Seconds, defaults to 0
33
35
  config.from_label = "From =>"
34
36
  config.to_label = "To =>"
35
37
  config.cc_label = "Cc =>"
36
38
  config.date_label = "Date =>"
37
- config.date_format = "%d.%m.%Y" # see Date#strftime
39
+ config.date_format do |date|
40
+ date.strftime("%Y")
41
+ end
38
42
  end
39
43
  ```
40
44
 
@@ -56,7 +60,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
56
60
 
57
61
  ## Contributing
58
62
 
59
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/eml_to_pdf. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
63
+ Bug reports and pull requests are welcome on GitHub at https://github.com/siegy22/eml_to_pdf. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
60
64
 
61
65
 
62
66
  ## License
data/Rakefile CHANGED
@@ -3,6 +3,7 @@ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new do |t|
5
5
  t.libs << 'test'
6
+ t.test_files = FileList['test/*_test.rb']
6
7
  end
7
8
 
8
9
  desc "Run tests"
@@ -19,11 +19,13 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.10"
23
- spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.required_ruby_version = ">= 2.2.0"
23
+
24
+ spec.add_development_dependency "bundler", ">= 1.10"
25
+ spec.add_development_dependency "rake", "~> 12.0"
24
26
  spec.add_development_dependency 'minitest', '~> 5.9'
25
27
 
26
28
  spec.add_runtime_dependency 'filesize', '~> 0.1.1'
27
29
  spec.add_runtime_dependency 'mail', '~> 2.5', '>= 2.5.4'
28
- spec.add_runtime_dependency 'nokogiri', '~> 1.6', '>= 1.6.7.2'
30
+ spec.add_runtime_dependency 'nokogiri', '~> 1.7'
29
31
  end
@@ -1,13 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- # TODO: use this to convert whole folders
3
- # Dir["test/fixtures/emails/*.eml"].each do |test_file|
4
- # puts "> converting #{test_file}"
5
- # begin
6
- # EmlToPdf.convert(test_file, "#{test_file[0..-5]}_output.pdf")
7
- # rescue NoMethodError => e
8
- # puts e.message
9
- # end
10
- # end
11
2
 
12
3
  if ARGV[0] && ARGV[1]
13
4
  require "bundler/setup"
@@ -5,6 +5,8 @@ require "eml_to_pdf/converter"
5
5
  require "eml_to_pdf/email"
6
6
  require "eml_to_pdf/wkhtmltopdf"
7
7
  require "eml_to_pdf/metadata_context"
8
+ require "eml_to_pdf/extraction_step"
9
+ require "eml_to_pdf/extraction_step_list"
8
10
 
9
11
  module EmlToPdf
10
12
  def self.convert(input, output)
@@ -1,22 +1,27 @@
1
1
  module EmlToPdf
2
2
  class Configuration
3
- attr_accessor :from_label, :to_label, :cc_label, :date_label
4
- attr_reader :date_format
3
+ attr_accessor :from_label, :to_label, :cc_label, :date_label, :wkhtmltopdf, :timeout
5
4
 
6
5
  def initialize
7
6
  @from_label = "From"
8
7
  @to_label = "To"
9
8
  @cc_label = "Cc"
10
9
  @date_label = "Date"
11
- @date_format = "%Y-%m-%d %H:%M:%S %z"
10
+ @date_format = lambda { |date| date.strftime("%Y-%m-%d %H:%M:%S %z") }
11
+ @wkhtmltopdf = 'wkhtmltopdf'
12
+ @timeout = 0
12
13
  end
13
14
 
14
- def date_format=(value)
15
- if value.is_a?(String)
16
- @date_format = value
15
+ def date_format(&block)
16
+ if block_given?
17
+ @date_format = block
17
18
  else
18
- raise ArgumentError, "You can only use a String to format the date. (See Date#strftime)"
19
+ @date_format
19
20
  end
20
21
  end
22
+
23
+ def format_date(date)
24
+ @date_format.call(date)
25
+ end
21
26
  end
22
27
  end
@@ -5,12 +5,6 @@ require "erb"
5
5
 
6
6
  module EmlToPdf
7
7
  class Email
8
- MIME_TYPES = {
9
- plain_text: "text/plain",
10
- html: "text/html",
11
- multipart_alternative: "multipart/alternative"
12
- }
13
-
14
8
  TEMPLATES_PATH = Pathname.new(File.expand_path(__dir__)) + "templates"
15
9
 
16
10
  def initialize(input_path)
@@ -19,26 +13,15 @@ module EmlToPdf
19
13
  end
20
14
 
21
15
  def to_html
22
- html = text_parts(@mail).join
23
- html = resolve_cids_from_attachments(html, @mail.attachments)
16
+ extraction = ExtractionStep.new(@mail)
17
+ extraction = extraction.next until extraction.finished?
18
+ html = extraction.to_html
19
+ html = resolve_cids_from_attachments(html, @mail.all_parts)
24
20
  html = add_mail_metadata_to_html(@mail, html)
25
21
  html
26
22
  end
27
23
 
28
24
  private
29
- def text_parts(mail_or_part)
30
- if mail_or_part.multipart? && multipart_alternative?(mail_or_part)
31
- best_part = extract_best_part(mail_or_part.parts)
32
- text_parts(best_part)
33
- elsif mail_or_part.multipart?
34
- mail_or_part.parts.map do |part|
35
- text_parts(part)
36
- end
37
- else
38
- [text_body(mail_or_part)]
39
- end.flatten
40
- end
41
-
42
25
  def visible_attachments(mail)
43
26
  mail.attachments.select do |attachment|
44
27
  !attachment.inline?
@@ -64,42 +47,6 @@ module EmlToPdf
64
47
  end
65
48
  end
66
49
 
67
- def extract_best_part(parts)
68
- if multipart_part = parts.detect(&:multipart?)
69
- multipart_part
70
- elsif html_part = find_body_with_type(parts, :html)
71
- html_part
72
- elsif text_part = find_body_with_type(parts, :plain_text)
73
- text_part
74
- else
75
- "can't find useable part"
76
- end
77
- end
78
-
79
- def find_body_with_type(parts, type)
80
- parts.detect do |part|
81
- part.mime_type == MIME_TYPES[type]
82
- end
83
- end
84
-
85
- def multipart_alternative?(part)
86
- part.mime_type == MIME_TYPES[:multipart_alternative]
87
- end
88
-
89
- def text_body(mail_or_part)
90
- if mail_or_part.mime_type == MIME_TYPES[:html] && !mail_or_part.attachment?
91
- mail_or_part.decoded
92
- elsif mail_or_part.mime_type == MIME_TYPES[:plain_text] && !mail_or_part.attachment?
93
- wrap_text_in_pre_tag(mail_or_part.decoded)
94
- else
95
- ""
96
- end
97
- end
98
-
99
- def wrap_text_in_pre_tag(text)
100
- "<pre>#{text}</pre>"
101
- end
102
-
103
50
  def add_mail_metadata_to_html(mail, html)
104
51
  context = MetadataContext.new(from: save_extract_header(mail, :from),
105
52
  to: save_extract_header(mail, :to),
@@ -123,11 +70,7 @@ module EmlToPdf
123
70
  end
124
71
 
125
72
  def save_extract_header(mail, header)
126
- if header = mail.header[header]
127
- header.decoded
128
- else
129
- ""
130
- end
73
+ (mail.header[header] && mail.header[header].decoded) || ""
131
74
  end
132
75
  end
133
76
  end
@@ -1,54 +1,63 @@
1
- module EmlToPdf
1
+ require 'eml_to_pdf/extraction_step_list'
2
+ require 'eml_to_pdf/empty_part'
2
3
 
3
- # TODO: in email#to_html remove recursive function with this class
4
- # for a better control and to be able to make more unit tests.
4
+ module EmlToPdf
5
5
  class ExtractionStep
6
+ MIME_TYPES = {
7
+ plain_text: "text/plain",
8
+ html: "text/html",
9
+ multipart_alternative: "multipart/alternative"
10
+ }
11
+
6
12
  def initialize(mail_or_part)
7
13
  @mail_or_part = mail_or_part
8
14
  end
9
15
 
10
- # extraction = ExtractionStep.new(@mail)
11
- # extraction = extraction.next until extraction.finished?
12
-
13
16
  def next
14
17
  if multipart_alternative?(@mail_or_part)
15
18
  best_part = extract_best_part(@mail_or_part.parts)
16
19
  ExtractionStep.new(best_part)
17
20
  elsif @mail_or_part.multipart?
18
-
21
+ ExtractionStepList.new(@mail_or_part.parts.map { |part| ExtractionStep.new(part) })
19
22
  else
20
-
23
+ self
21
24
  end
22
25
  end
23
26
 
24
27
  def finished?
25
- @mail_or_part.parts.none?(&:multipart?)
28
+ !@mail_or_part.multipart?
26
29
  end
27
30
 
28
31
  def to_html
29
- if html_part = @mail_or_part.html_part
30
- html_part
31
- elsif text_part = @mail_or_part.text_part
32
- wrap_text_in_pre_tag(text_part)
32
+ text_body(@mail_or_part)
33
+ end
34
+
35
+ private
36
+ def multipart_alternative?(part)
37
+ part.mime_type == MIME_TYPES[:multipart_alternative]
38
+ end
39
+
40
+ def text_body(mail_or_part)
41
+ if mail_or_part.mime_type == MIME_TYPES[:html] && !mail_or_part.attachment?
42
+ mail_or_part.decoded
43
+ elsif mail_or_part.mime_type == MIME_TYPES[:plain_text] && !mail_or_part.attachment?
44
+ wrap_text_in_pre_tag(mail_or_part.decoded)
33
45
  else
34
46
  ""
35
47
  end
36
48
  end
37
49
 
38
50
  def extract_best_part(parts)
39
- if multipart_part = parts.detect(&:multipart?)
40
- multipart_part
41
- elsif html_part = find_body_with_type(parts, :html)
42
- html_part
43
- elsif text_part = find_body_with_type(parts, :plain_text)
44
- text_part
45
- else
46
- "can't find useable part"
47
- end
51
+ parts.detect(&:multipart?) ||
52
+ find_body_with_type(parts, :html) ||
53
+ find_body_with_type(parts, :plain_text) ||
54
+ EmlToPdf::EmptyPart.new
48
55
  end
49
56
 
50
- def multipart_alternative?(part)
51
- part.mime_type == MIME_TYPES[:multipart_alternative]
57
+ def find_body_with_type(parts, type)
58
+ parts.detect do |part|
59
+ part.mime_type == MIME_TYPES[type]
60
+ end
52
61
  end
53
62
 
54
63
  def wrap_text_in_pre_tag(text)
@@ -0,0 +1,24 @@
1
+ module EmlToPdf
2
+ class ExtractionStepList
3
+ def initialize(steps)
4
+ @steps = steps
5
+ end
6
+
7
+ def next
8
+ self.class.new(@steps.map(&:next))
9
+ end
10
+
11
+ def finished?
12
+ @steps.all?(&:finished?)
13
+ end
14
+
15
+ def to_html
16
+ @steps.flatten.map(&:to_html).join
17
+ end
18
+
19
+ private
20
+ def multipart_alternative?(part)
21
+ part.mime_type == MIME_TYPES[:multipart_alternative]
22
+ end
23
+ end
24
+ end
@@ -1,14 +1,9 @@
1
1
  require "filesize"
2
2
  require "cgi"
3
+ require "ostruct"
3
4
 
4
5
  module EmlToPdf
5
- class MetadataContext
6
- def initialize(metadata)
7
- metadata.each do |k, v|
8
- eval("@#{k}=v")
9
- end
10
- end
11
-
6
+ class MetadataContext < OpenStruct
12
7
  def config
13
8
  EmlToPdf.configuration
14
9
  end
@@ -18,7 +13,7 @@ module EmlToPdf
18
13
  end
19
14
 
20
15
  def format_date(date)
21
- date.strftime(config.date_format)
16
+ config.format_date(date)
22
17
  end
23
18
 
24
19
  def html_escape(str)
@@ -3,25 +3,25 @@
3
3
  <table>
4
4
  <tr>
5
5
  <td><strong><%= config.from_label %></strong></td>
6
- <td><%= html_escape(@from) %></td>
6
+ <td><%= html_escape(from) %></td>
7
7
  </tr>
8
8
  <tr>
9
9
  <td><strong><%= config.to_label %></strong></td>
10
- <td><%= html_escape(@to) %></td>
10
+ <td><%= html_escape(to) %></td>
11
11
  </tr>
12
12
  <tr>
13
13
  <td><strong><%= config.cc_label %></strong></td>
14
- <td><%= html_escape(@cc) %></td>
14
+ <td><%= html_escape(cc) %></td>
15
15
  </tr>
16
16
  <tr>
17
17
  <td><strong><%= config.date_label %></strong></td>
18
- <td><%= format_date(@date) if @date %></td>
18
+ <td><%= format_date(date) if date %></td>
19
19
  </tr>
20
20
  </table>
21
- <h3><%= @subject %></h3>
21
+ <h3><%= subject %></h3>
22
22
  <hr>
23
23
  <ul class="email-attachments">
24
- <% @attachments.each do |att| %>
24
+ <% attachments.each do |att| %>
25
25
  <li class="attachement">
26
26
  <span class="filename"><%= att.filename %></span>
27
27
  <span class="file-size"><%= format_attachment_size(att) %></span>
@@ -1,3 +1,3 @@
1
1
  module EmlToPdf
2
- VERSION = "0.2.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -1,10 +1,25 @@
1
+ require 'timeout'
2
+
1
3
  module EmlToPdf
2
4
  class Wkhtmltopdf
5
+ class ConversionError < StandardError; end
6
+ class ConversionTimeoutError < StandardError
7
+ def message
8
+ "Failed to convert within the configured timeout. Use EmlToPdf.configure to increase the timeout if needed."
9
+ end
10
+ end
11
+
3
12
  def self.convert(input, output_path)
4
- IO.popen("wkhtmltopdf --encoding utf-8 --footer-center [page] --footer-spacing 2.5 - #{output_path} 2>&1", "r+") do |pipe|
5
- pipe.puts(input)
6
- pipe.close_write
7
- pipe.readlines # TODO save output
13
+ Timeout.timeout(EmlToPdf.configuration.timeout, ConversionTimeoutError) do
14
+ IO.popen("#{EmlToPdf.configuration.wkhtmltopdf} --encoding utf-8 --footer-center [page] --footer-spacing 2.5 --quiet - #{output_path} 2>&1", "r+") do |pipe|
15
+ pipe.puts(input)
16
+ pipe.close_write
17
+ output = pipe.readlines.join
18
+ pipe.close
19
+ unless $?.success?
20
+ raise ConversionError, output
21
+ end
22
+ end
8
23
  end
9
24
  end
10
25
  end
File without changes
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eml_to_pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yves Siegrist
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-09 00:00:00.000000000 Z
11
+ date: 2020-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.10'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.10'
27
27
  - !ruby/object:Gem::Dependency
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '12.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '12.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -92,20 +92,14 @@ dependencies:
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '1.6'
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- version: 1.6.7.2
95
+ version: '1.7'
99
96
  type: :runtime
100
97
  prerelease: false
101
98
  version_requirements: !ruby/object:Gem::Requirement
102
99
  requirements:
103
100
  - - "~>"
104
101
  - !ruby/object:Gem::Version
105
- version: '1.6'
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- version: 1.6.7.2
102
+ version: '1.7'
109
103
  description: This gem uses wkhtmltopdf to convert an eml to a pdf. (eml -> html ->
110
104
  pdf)
111
105
  email:
@@ -115,6 +109,7 @@ executables:
115
109
  extensions: []
116
110
  extra_rdoc_files: []
117
111
  files:
112
+ - ".codeclimate.yml"
118
113
  - ".gitignore"
119
114
  - ".ruby-version"
120
115
  - ".travis.yml"
@@ -133,11 +128,13 @@ files:
133
128
  - lib/eml_to_pdf/email.rb
134
129
  - lib/eml_to_pdf/empty_part.rb
135
130
  - lib/eml_to_pdf/extraction_step.rb
131
+ - lib/eml_to_pdf/extraction_step_list.rb
136
132
  - lib/eml_to_pdf/metadata_context.rb
137
133
  - lib/eml_to_pdf/templates/heading.html.erb
138
134
  - lib/eml_to_pdf/templates/style.html
139
135
  - lib/eml_to_pdf/version.rb
140
136
  - lib/eml_to_pdf/wkhtmltopdf.rb
137
+ - tmp/.gitkeep
141
138
  homepage: https://github.com/Elektron1c97/eml_to_pdf
142
139
  licenses:
143
140
  - MIT
@@ -150,15 +147,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
147
  requirements:
151
148
  - - ">="
152
149
  - !ruby/object:Gem::Version
153
- version: '0'
150
+ version: 2.2.0
154
151
  required_rubygems_version: !ruby/object:Gem::Requirement
155
152
  requirements:
156
153
  - - ">="
157
154
  - !ruby/object:Gem::Version
158
155
  version: '0'
159
156
  requirements: []
160
- rubyforge_project:
161
- rubygems_version: 2.4.5
157
+ rubygems_version: 3.1.2
162
158
  signing_key:
163
159
  specification_version: 4
164
160
  summary: This gem allows you to convert an eml (email) into a pdf.