mail-jenc 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5a854118202e49e07a327bfd1e4ed4e4454d3106cb11d2bf37862511bd995f18
4
+ data.tar.gz: 2d0df7569232ed77e15c42e0ce0ed7ccadbbec2a1f80e3e2a8ad1365ccbd0910
5
+ SHA512:
6
+ metadata.gz: 0fb0376402c784705aae16a7a7e836c6c8aa1f8555a002b924dc1154b46ca3c98287558c9a028127c7505f485e991d0786f075e8c67f6cdf05e5390968f3f472
7
+ data.tar.gz: 1186fe098ff229094d78b8ae72abdd5a49a837397c5bc71f7922a60ce8c6918a61a67969c9ad59a9e6800111f72f897181d224af3de7cff5427fdd57a82dd33c
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Mail::Jenc
2
+
3
+ A mail patch for encoding conventional mail.
4
+
5
+ ## Dependencies
6
+
7
+ * ruby 2.3+
8
+ * mail 2.7
9
+
10
+ ## Installation
11
+
12
+ Add to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'mail-jenc'
16
+ ```
17
+
18
+ Then run:
19
+
20
+ $ bundle install
21
+
22
+ ## Usage
23
+
24
+ Use mail as usual. You can enable/disable patched features as follows:
25
+
26
+ ```ruby
27
+ # disable patch
28
+ Mail::Jenc.disable
29
+
30
+ # enable patch
31
+ Mail::Jenc.enable
32
+ ```
33
+
34
+ ## Contributing
35
+
36
+ Pull requests are welcome on GitHub at https://github.com/kanety/mail-jenc.
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,30 @@
1
+ module Mail
2
+ module Jenc
3
+ module AttachmentsListPatch
4
+ def []=(name, value)
5
+ if Jenc.enabled?
6
+ if name && !name.ascii_only? && value.is_a?(Hash) && (charset = value.delete(:header_charset))
7
+ mime_type = set_mime_type(name)
8
+ transcoded = Mail::Encodings.transcode_charset(name, name.encoding, charset)
9
+ if Jenc.rfc2231
10
+ encoded = RFC2231Encoder.encode(transcoded, charset: charset)
11
+ value[:content_disposition] ||= %Q|#{@content_disposition_type}; #{encoded}|
12
+ encoded = Mail::Encodings.b_value_encode(transcoded)
13
+ value[:content_type] ||= %Q|#{mime_type}; name="#{encoded}"|
14
+ else
15
+ encoded = Mail::Encodings.b_value_encode(transcoded)
16
+ value[:content_disposition] ||= %Q|#{@content_disposition_type}; filename="#{encoded}"|
17
+ value[:content_type] ||= %Q|#{mime_type}; name="#{encoded}"|
18
+ end
19
+ value[:transfer_encoding] = 'binary'
20
+ end
21
+ end
22
+ super
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ unless Mail::AttachmentsList.included_modules.include?(Mail::Jenc::AttachmentsListPatch)
29
+ Mail::AttachmentsList.prepend Mail::Jenc::AttachmentsListPatch
30
+ end
@@ -0,0 +1,47 @@
1
+ module Mail
2
+ module Jenc
3
+ module PercentEncoder
4
+ class << self
5
+ def encode(str)
6
+ encode_to_array(str).join
7
+ end
8
+
9
+ def encode_to_array(str)
10
+ str.unpack('H*').first.scan(/.{2}/).map { |hex| "%#{hex.upcase}" }
11
+ end
12
+ end
13
+ end
14
+
15
+ module RFC2231Encoder
16
+ class << self
17
+ def encode(name, options = {})
18
+ encode_to_hash(name, options).map { |k, v| "#{k}=#{v}" }.join(";\r\n\s")
19
+ end
20
+
21
+ def encode_to_hash(name, key: 'filename', charset: 'utf-8')
22
+ hexes = name.unpack('H*')[0].scan(/.{2}/).map { |hex| "%#{hex.upcase}" }
23
+
24
+ first_hex_num = hex_num(charset.size + key.size + 3)
25
+ if hexes.size <= first_hex_num
26
+ params = { "#{key}*" => "#{charset.downcase}''#{hexes.join}" }
27
+ else
28
+ params = { "#{key}*0*" => "#{charset.downcase}''#{hexes.shift(first_hex_num).join}" }
29
+ slices = hexes.each_slice(hex_num(key.size + 3))
30
+ slices.each_with_index do |sliced, i|
31
+ kc = "#{key}*#{i+1}*"
32
+ params[kc] = sliced.join
33
+ end
34
+ end
35
+
36
+ params
37
+ end
38
+
39
+ private
40
+
41
+ def hex_num(size)
42
+ ((80 - 4 - size).to_f / 3).to_i
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,29 @@
1
+ module Mail
2
+ module Jenc
3
+ module AddressFieldPatch
4
+ def initialize(value, charset = nil)
5
+ if Jenc.enabled?
6
+ if value.is_a?(String) && !value.ascii_only? && charset && charset != 'utf-8'
7
+ list = Mail::AddressList.new(value)
8
+ list.addresses.each do |addr|
9
+ if addr.display_name && !addr.display_name.ascii_only?
10
+ addr.display_name = Mail::Encodings.b_value_encode(
11
+ Mail::Encodings.transcode_charset(addr.display_name, addr.display_name.encoding, charset)
12
+ )
13
+ end
14
+ end
15
+ value = list.addresses.map(&:encoded).join(', ')
16
+ end
17
+ end
18
+ super
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ klasses = ObjectSpace.each_object(Class).select { |klass| klass < Mail::CommonAddress }
25
+ klasses.each do |klass|
26
+ unless klass.included_modules.include?(Mail::Jenc::AddressFieldPatch)
27
+ klass.prepend Mail::Jenc::AddressFieldPatch
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ module Mail
2
+ module Jenc
3
+ module UnstructuredFieldPatch
4
+ def initialize(name, value, charset = nil)
5
+ if Jenc.enabled?
6
+ if value.is_a?(String)
7
+ if value.ascii_only?
8
+ charset = 'us-ascii'
9
+ value.force_encoding('us-ascii')
10
+ elsif charset && charset != 'utf-8'
11
+ value = Mail::Encodings.b_value_encode(
12
+ Mail::Encodings.transcode_charset(value, value.encoding, charset)
13
+ )
14
+ end
15
+ end
16
+ end
17
+ super
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ unless Mail::UnstructuredField.included_modules.include?(Mail::Jenc::UnstructuredFieldPatch)
24
+ Mail::UnstructuredField.prepend Mail::Jenc::UnstructuredFieldPatch
25
+ end
@@ -0,0 +1,29 @@
1
+ module Mail
2
+ module Jenc
3
+ module MessagePatch
4
+ def body=(value)
5
+ if Jenc.enabled?
6
+ if value.is_a?(String) && !value.ascii_only? && charset && charset != 'utf-8' && @transport_encoding.to_s != '8bit'
7
+ value = Mail::Encodings.transcode_charset(value, value.encoding, charset)
8
+ value.force_encoding('us-ascii') if @transport_encoding.to_s == '7bit'
9
+ value = @transport_encoding.encode(value)
10
+ end
11
+ end
12
+ super
13
+ end
14
+
15
+ def add_file(values)
16
+ if Jenc.enabled?
17
+ if values.is_a?(Hash) && charset
18
+ values[:header_charset] = charset
19
+ end
20
+ end
21
+ super
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ unless Mail::Message.included_modules.include?(Mail::Jenc::MessagePatch)
28
+ Mail::Message.prepend Mail::Jenc::MessagePatch
29
+ end
@@ -0,0 +1,24 @@
1
+ module Mail
2
+ module Jenc
3
+ module Ruby19Patch
4
+ def transcode_charset(str, from_encoding, to_encoding = Encoding::UTF_8)
5
+ if Jenc.enabled?
6
+ coded = super(str, from_encoding, Ruby19Patch.preferred_charset(to_encoding))
7
+ coded.force_encoding(to_encoding)
8
+ else
9
+ super
10
+ end
11
+ end
12
+
13
+ class << self
14
+ def preferred_charset(charset)
15
+ Jenc.preferred_charsets[charset.to_s.downcase] || charset
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ unless Mail::Ruby19.singleton_class.included_modules.include?(Mail::Jenc::Ruby19Patch)
23
+ Mail::Ruby19.singleton_class.prepend Mail::Jenc::Ruby19Patch
24
+ end
@@ -0,0 +1,5 @@
1
+ module Mail
2
+ module Jenc
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
data/lib/mail/jenc.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'mail'
2
+
3
+ Dir["#{__dir__}/jenc/**/*.rb"].each do |file|
4
+ require file
5
+ end
6
+
7
+ module Mail
8
+ module Jenc
9
+ class << self
10
+ attr_reader :enabled
11
+ attr_accessor :rfc2231
12
+ attr_accessor :preferred_charsets
13
+
14
+ def enabled?
15
+ @@enabled
16
+ end
17
+
18
+ def enable
19
+ @@enabled = true
20
+ end
21
+
22
+ def disable
23
+ @@enabled = false
24
+ end
25
+ end
26
+
27
+ self.enable
28
+ self.rfc2231 = true
29
+ self.preferred_charsets = {
30
+ 'iso-2022-jp' => 'cp50221',
31
+ 'shift_jis' => 'cp932'
32
+ }
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mail-jenc
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yoshikazu Kaneta
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mail
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.7.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.7.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A mail patch for encoding conventional mail
70
+ email:
71
+ - kaneta@sitebridge.co.jp
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - README.md
77
+ - Rakefile
78
+ - lib/mail/jenc.rb
79
+ - lib/mail/jenc/attachments_list_patch.rb
80
+ - lib/mail/jenc/encoder.rb
81
+ - lib/mail/jenc/fields/address_field_patch.rb
82
+ - lib/mail/jenc/fields/unstructured_field_patch.rb
83
+ - lib/mail/jenc/message_patch.rb
84
+ - lib/mail/jenc/ruby_1_9_patch.rb
85
+ - lib/mail/jenc/version.rb
86
+ homepage: https://github.com/kanety/mail-jenc
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubygems_version: 3.0.1
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: A mail patch for encoding conventional mail
109
+ test_files: []