extended_email_reply_parser 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 57e1fcc1b76d54e57566cf2c775967d99cc7a991
4
+ data.tar.gz: 52f31cfb6238fe4c2322b4bef77b0e7cc63c2ed7
5
+ SHA512:
6
+ metadata.gz: b1a103c7bd67ec89fa1d0cbdf9f15a10f50a733aa9f58ad4b2d960abded59759732fb9b237834e05042be006c38ce76c43ef553a34a09fa430dbfa368c2e0011
7
+ data.tar.gz: cd1994764092fc0c9b45b6410fbf4d5e5187595fe400f1d238dc28f7abd9b8b81e8fe9daa097e5e19c3fbb7ebc88364ee2795f87a436c33a2f895a4ffe5787cd
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
data/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ This project adheres to [Semantic Versioning](http://semver.org/).
5
+
6
+ ## master (unreleased)
7
+ ### Security
8
+ ### Added
9
+ ### Deprecated
10
+ ### Removed
11
+ ### Fixed
12
+
13
+ ## ExtendedEmailReplyParser 0.1.0 (2016-07-22)
14
+ ### Added
15
+ - `ExtendedEmailReplyParser.read "/path/to/email.eml"` returns the corresponding `Mail::Message` object.
16
+ - `ExtendedEmailReplyParser.read("/path/to/email.eml").extract_text` returns the email body text in utf-8. See also: http://stackoverflow.com/a/15818886/2066546
17
+ - Methods for parsing emails: `ExtendedEmailReplyParser.parse("/path/to/email.eml")`, `ExtendedEmailReplyParser.parse(message)`, `ExtendedEmailReplyParser.parse(body_text)`, `Mail::Message#parse`.
18
+ - Allowing to chain custom parsers. A parser inherits from `ExtendedEmailReplyParser::Parsers::Base` and needs to implement a `parse` method. The parser is automatically chained along with the others when calling `ExtendedEmailReplyParser.parse` or `MailMessage#parse`.
19
+ - Wrapping the original [github/email_reply_parser](https://github.com/github/email_reply_parser) in `ExtendedEmailReplyParser::Parsers::Github`.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in extended_email_reply_parser.gemspec
4
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Sebastian Fiedlschuster
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # ExtendedEmailReplyParser
2
+
3
+ [![Build Status](https://travis-ci.org/fiedl/extended_email_reply_parser.svg?branch=master)](https://travis-ci.org/fiedl/extended_email_reply_parser)
4
+
5
+ When implementing a "reply or comment by email" feature, it's neccessary to filter out signatures and the previous conversation. One needs to extract just the relevant parts for the conversation or comment section of the application. This is what this [ruby](https://www.ruby-lang.org) gem helps to do.
6
+
7
+ This gem is an extended version of [github's `email_reply_parser`](https://github.com/github/email_reply_parser). It wraps the original email_reply_parser and allows to build extensions such as support for i18n and detecting previous conversation that is not properly marked as quotation by the sender's mail client.
8
+
9
+ ## Usage
10
+
11
+ ### Parsing incoming emails
12
+
13
+ To extract the relevant text of an email reply, call `ExtendedEmailReplyParser.parse`, which accepts either a path to the email file, or a `Mail::Message` object, or the email body text itself, and returns the parsed, i.e. relevant text, which can be used as comment in the application
14
+
15
+ ```ruby
16
+ ExtendedEmailReplyParser.parse "/path/to/email.eml"
17
+ ExtendedEmailReplyParser.parse message
18
+ ExtendedEmailReplyParser.parse body_text # => parsed text as String
19
+ ```
20
+
21
+ Or, if you prefer to call `#parse` on the `Mail::Message`:
22
+
23
+ ```ruby
24
+ message.parse # => parsed text as String
25
+ ```
26
+
27
+ For example, for a incoming `Mail::Message`, `message`:
28
+
29
+ ```ruby
30
+ @comment.author = User.where(email: message.from.first).first
31
+ @comment.text = ExtendedEmailReplyParser.parse message
32
+ @comment.save!
33
+ ```
34
+
35
+ ### Extracting the body text
36
+
37
+ This gem extends [Mail::Message](https://github.com/mikel/mail/blob/master/lib/mail/message.rb) to conveniently extract the text body as utf-8.
38
+
39
+ ```ruby
40
+ message.extract_text
41
+ ```
42
+
43
+ There's also a convenience method to extract the body text from an email file:
44
+
45
+ ```ruby
46
+ ExtendedEmailReplyParser.read "/path/to/email.eml" # => Mail::Message
47
+ ExtendedEmailReplyParser.read("/path/to/email.eml").extract_text # => String
48
+ ```
49
+
50
+ ### Writing a parser
51
+
52
+ The parsing system allows you to add your own parser to the parsing chain. Just define a class inheriting from `ExtendedEmailReplyParser::Parsers::Base` and implement a `parse` method. The text before parsing is accessed via `text`.
53
+
54
+ ```ruby
55
+ # app/models/email_parsers/my_parser.rb
56
+ class EmailParsers::ShoutParser < ExtendedEmailReplyParser::Parsers::Base
57
+
58
+ # This parser SHOUTS THE WHOLE EMAIL.
59
+ # The text before parsing is accessed by `text`.
60
+ #
61
+ def parse
62
+ text.upcase
63
+ end
64
+ end
65
+ ```
66
+
67
+ ### Selecting parsers to use
68
+
69
+ By default, all parsers that inherit from `ExtendedEmailReplyParser::Parsers::Base` are used. One simply has to call:
70
+
71
+ ```ruby
72
+ ExtendedEmailReplyParser.parse message
73
+ ```
74
+
75
+ In order to select specific parsers, just chain them yourself:
76
+
77
+ ```ruby
78
+ EmailParsers::ShoutParser.parse \
79
+ ExtendedEmailReplyParser::Parsers::Github.parse \
80
+ message
81
+ ```
82
+
83
+
84
+
85
+ ## Installation
86
+
87
+ Add this line to your application's Gemfile:
88
+
89
+ ```ruby
90
+ # Gemfile
91
+ gem 'extended_email_reply_parser'
92
+ ```
93
+
94
+ And then execute:
95
+
96
+ ➜ bundle
97
+
98
+ Or install it yourself as:
99
+
100
+ ➜ gem install extended_email_reply_parser
101
+
102
+ ## Development
103
+
104
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
105
+
106
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
107
+
108
+ ## Contributing
109
+
110
+ Bug reports and pull requests are welcome on GitHub at https://github.com/fiedl/extended_email_reply_parser.
111
+
112
+
113
+ ## License
114
+
115
+ The gem is available as open source under the terms of the [MIT License](MIT-LICENSE).
116
+
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
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "extended_email_reply_parser"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'extended_email_reply_parser/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "extended_email_reply_parser"
8
+ spec.version = ExtendedEmailReplyParser::VERSION
9
+ spec.authors = ["Sebastian Fiedlschuster"]
10
+ spec.email = ["sebastian@fiedlschuster.de"]
11
+
12
+ spec.summary = "This is an extended version of github's email_reply_parser."
13
+ spec.description = spec.description
14
+ spec.homepage = "https://github.com/fiedl/extended_email_reply_parser"
15
+ spec.license = "MIT"
16
+
17
+ if spec.respond_to?(:metadata)
18
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
19
+ else
20
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
21
+ end
22
+
23
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.12"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ spec.add_development_dependency 'pry'
30
+
31
+ spec.add_dependency 'email_reply_parser', '~> 0.5.9'
32
+ spec.add_dependency 'mail'
33
+ spec.add_dependency 'charlock_holmes'
34
+ spec.add_dependency 'activesupport'
35
+ end
@@ -0,0 +1,28 @@
1
+ # This extends the `Mail::Message` object of https://github.com/mikel/mail
2
+ # in order to allow:
3
+ #
4
+ # (message.html_part || message.text_part || message).body_in_utf8
5
+ #
6
+ # See also: http://stackoverflow.com/a/15818886/2066546
7
+ #
8
+ module Mail
9
+ class Message
10
+ def body_in_utf8
11
+ require 'charlock_holmes/string'
12
+ body = self.body.decoded
13
+ if body.present?
14
+ encoding = body.detect_encoding[:encoding]
15
+ body = body.force_encoding(encoding).encode('UTF-8')
16
+ end
17
+ return body
18
+ end
19
+
20
+ def extract_text
21
+ (self.text_part || (self if self.content_type.include?('text/plain'))).body_in_utf8
22
+ end
23
+
24
+ def parse
25
+ ExtendedEmailReplyParser.parse self
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,19 @@
1
+ module ExtendedEmailReplyParser
2
+ class Parsers::Base
3
+
4
+ attr_accessor :text
5
+
6
+ def initialize(text_before_parsing)
7
+ self.text = text_before_parsing
8
+ end
9
+
10
+ def parse
11
+ return text
12
+ end
13
+
14
+
15
+ def self.subclasses
16
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ module ExtendedEmailReplyParser
2
+ class Parsers::Github < Parsers::Base
3
+
4
+ def parse
5
+ EmailReplyParser.parse_reply text
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ module ExtendedEmailReplyParser
2
+ module Parsers
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module ExtendedEmailReplyParser
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,73 @@
1
+ require 'mail'
2
+ require 'charlock_holmes'
3
+ require 'email_reply_parser'
4
+ require 'active_support'
5
+ require 'active_support/core_ext/object/blank'
6
+ require 'extended_email_reply_parser/mail/message'
7
+ require 'extended_email_reply_parser/parsers'
8
+ require 'extended_email_reply_parser/parsers/base'
9
+ Dir.glob(File.dirname(File.absolute_path(__FILE__)) + "/extended_email_reply_parser/parsers/*") { |file| require file }
10
+
11
+ require 'extended_email_reply_parser/version'
12
+
13
+ # Usage:
14
+ #
15
+ # ExtendedEmailReplyParser.parse "/path/to/email.eml"
16
+ # ExtendedEmailReplyParser.parse mail_message
17
+ # ExtendedEmailReplyParser.parse MyReplyModel.find(123).text_content
18
+ #
19
+ module ExtendedEmailReplyParser
20
+
21
+ # Read an email file and return a parsable `Mail::Message` object.
22
+ # `Mail::Message` is defined in https://github.com/mikel/mail and
23
+ # slightly extended in this gem.
24
+ #
25
+ # Examples:
26
+ #
27
+ # ExtendedEmailReplyParser.read "/path/to/email.eml"
28
+ # ExtendedEmailReplyParser.read("/path/to/email.eml").parse
29
+ # ExtendedEmailReplyParser.read("/path/to/email.eml").class # => Mail::Message
30
+ #
31
+ # or, maybe, you are looking for this:
32
+ #
33
+ # ExtendedEmailReplyParser.parse "/path/to/email.eml"
34
+ #
35
+ def self.read(email_file_path)
36
+ Mail.read email_file_path
37
+ end
38
+
39
+ # This parses the given object, i.e. removes quoted replies etc.
40
+ #
41
+ # Examples:
42
+ #
43
+ # ExtendedEmailReplyParser.parse "/path/to/email.eml"
44
+ # ExtendedEmailReplyParser.parse mail_message
45
+ # ExtendedEmailReplyParser.parse MyReplyModel.find(123).text_content
46
+ #
47
+ def self.parse(object)
48
+ if object.kind_of? String and File.file? object
49
+ self.parse_file object
50
+ elsif object.kind_of? String
51
+ self.parse_text object
52
+ elsif object.kind_of? Mail::Message
53
+ self.parse_message object
54
+ end
55
+ end
56
+
57
+ def self.parse_file(file_path)
58
+ self.parse_message Mail.read file_path
59
+ end
60
+
61
+ def self.parse_message(message)
62
+ self.parse_text message.extract_text
63
+ end
64
+
65
+ def self.parse_text(text)
66
+ parsed_text = text
67
+ Parsers::Base.subclasses.each do |parser_class|
68
+ parsed_text = parser_class.new(parsed_text).parse
69
+ end
70
+ parsed_text
71
+ end
72
+
73
+ end
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: extended_email_reply_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sebastian Fiedlschuster
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.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: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
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
+ - !ruby/object:Gem::Dependency
70
+ name: email_reply_parser
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.5.9
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.5.9
83
+ - !ruby/object:Gem::Dependency
84
+ name: mail
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: charlock_holmes
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: ''
126
+ email:
127
+ - sebastian@fiedlschuster.de
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".rspec"
134
+ - ".travis.yml"
135
+ - CHANGELOG.md
136
+ - Gemfile
137
+ - MIT-LICENSE
138
+ - README.md
139
+ - Rakefile
140
+ - bin/console
141
+ - bin/setup
142
+ - extended_email_reply_parser.gemspec
143
+ - lib/extended_email_reply_parser.rb
144
+ - lib/extended_email_reply_parser/mail/message.rb
145
+ - lib/extended_email_reply_parser/parsers.rb
146
+ - lib/extended_email_reply_parser/parsers/base.rb
147
+ - lib/extended_email_reply_parser/parsers/github.rb
148
+ - lib/extended_email_reply_parser/version.rb
149
+ homepage: https://github.com/fiedl/extended_email_reply_parser
150
+ licenses:
151
+ - MIT
152
+ metadata:
153
+ allowed_push_host: https://rubygems.org
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ required_rubygems_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ requirements: []
169
+ rubyforge_project:
170
+ rubygems_version: 2.5.1
171
+ signing_key:
172
+ specification_version: 4
173
+ summary: This is an extended version of github's email_reply_parser.
174
+ test_files: []