runger_email_reply_trimmer 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +72 -0
- data/LICENSE +9 -0
- data/README.md +21 -0
- data/Rakefile +17 -0
- data/bin/release +27 -0
- data/lib/runger_email_reply_trimmer/delimiter_matcher.rb +12 -0
- data/lib/runger_email_reply_trimmer/email_header_matcher.rb +72 -0
- data/lib/runger_email_reply_trimmer/embedded_email_matcher.rb +158 -0
- data/lib/runger_email_reply_trimmer/empty_line_matcher.rb +9 -0
- data/lib/runger_email_reply_trimmer/quote_matcher.rb +9 -0
- data/lib/runger_email_reply_trimmer/signature_matcher.rb +52 -0
- data/lib/runger_email_reply_trimmer/version.rb +5 -0
- data/lib/runger_email_reply_trimmer.rb +226 -0
- data/runger_email_reply_trimmer.gemspec +21 -0
- data/test/before/email_headers_1.txt +1 -0
- data/test/before/email_headers_2.txt +1 -0
- data/test/before/email_headers_3.txt +1 -0
- data/test/before/email_headers_4.txt +1 -0
- data/test/before/embedded_email_10.txt +25 -0
- data/test/before/embedded_email_german_3.txt +1 -0
- data/test/before/embedded_email_spanish_2.txt +1 -0
- data/test/before/forwarded_apple.txt +1 -0
- data/test/before/forwarded_gmail.txt +1 -0
- data/test/before/forwarded_message.txt +0 -0
- data/test/elided/delimiters.txt +10 -0
- data/test/elided/dual_embedded.txt +10 -0
- data/test/elided/email_headers_1.txt +14 -0
- data/test/elided/email_headers_2.txt +9 -0
- data/test/elided/email_headers_3.txt +16 -0
- data/test/elided/email_headers_4.txt +15 -0
- data/test/elided/email_headers_5.txt +23 -0
- data/test/elided/embedded_ception.txt +38 -0
- data/test/elided/embedded_email_1.txt +6 -0
- data/test/elided/embedded_email_10.txt +40 -0
- data/test/elided/embedded_email_11.txt +3 -0
- data/test/elided/embedded_email_12.txt +8 -0
- data/test/elided/embedded_email_13.txt +9 -0
- data/test/elided/embedded_email_14.txt +11 -0
- data/test/elided/embedded_email_15.txt +4 -0
- data/test/elided/embedded_email_16.txt +4 -0
- data/test/elided/embedded_email_17.txt +2 -0
- data/test/elided/embedded_email_18.txt +1 -0
- data/test/elided/embedded_email_19.txt +0 -0
- data/test/elided/embedded_email_2.txt +9 -0
- data/test/elided/embedded_email_3.txt +14 -0
- data/test/elided/embedded_email_4.txt +15 -0
- data/test/elided/embedded_email_5.txt +3 -0
- data/test/elided/embedded_email_6.txt +3 -0
- data/test/elided/embedded_email_7.txt +10 -0
- data/test/elided/embedded_email_8.txt +3 -0
- data/test/elided/embedded_email_9.txt +3 -0
- data/test/elided/embedded_email_chinese.txt +4 -0
- data/test/elided/embedded_email_dutch_1.txt +10 -0
- data/test/elided/embedded_email_dutch_2.txt +59 -0
- data/test/elided/embedded_email_french_1.txt +9 -0
- data/test/elided/embedded_email_french_2.txt +19 -0
- data/test/elided/embedded_email_german_1.txt +22 -0
- data/test/elided/embedded_email_german_2.txt +3 -0
- data/test/elided/embedded_email_german_3.txt +7 -0
- data/test/elided/embedded_email_german_4.txt +15 -0
- data/test/elided/embedded_email_german_5.txt +20 -0
- data/test/elided/embedded_email_german_6.txt +8 -0
- data/test/elided/embedded_email_italian.txt +28 -0
- data/test/elided/embedded_email_norwegian.txt +9 -0
- data/test/elided/embedded_email_polish_1.txt +32 -0
- data/test/elided/embedded_email_polish_2.txt +7 -0
- data/test/elided/embedded_email_portuguese.txt +14 -0
- data/test/elided/embedded_email_quote_text.txt +6 -0
- data/test/elided/embedded_email_russian_1.txt +25 -0
- data/test/elided/embedded_email_russian_2.txt +23 -0
- data/test/elided/embedded_email_spanish_1.txt +32 -0
- data/test/elided/embedded_email_spanish_2.txt +10 -0
- data/test/elided/embedded_email_swedish.txt +8 -0
- data/test/elided/embedded_email_ukrainian.txt +17 -0
- data/test/elided/forwarded_apple.txt +15 -0
- data/test/elided/forwarded_gmail.txt +15 -0
- data/test/elided/forwarded_message.txt +6 -0
- data/test/elided/normalize_line_endings.txt +0 -0
- data/test/elided/quote_and_text.txt +0 -0
- data/test/elided/quote_only.txt +0 -0
- data/test/elided/retains_spaces_and_formatting.txt +0 -0
- data/test/elided/signatures.txt +31 -0
- data/test/elided/spam_1.txt +75 -0
- data/test/elided/spam_2.txt +152 -0
- data/test/elided/strip.txt +0 -0
- data/test/elided/text_only.txt +0 -0
- data/test/elided/usenet.txt +7 -0
- data/test/emails/delimiters.txt +14 -0
- data/test/emails/dual_embedded.txt +13 -0
- data/test/emails/email_headers_1.txt +17 -0
- data/test/emails/email_headers_2.txt +10 -0
- data/test/emails/email_headers_3.txt +18 -0
- data/test/emails/email_headers_4.txt +17 -0
- data/test/emails/email_headers_5.txt +37 -0
- data/test/emails/embedded_ception.txt +47 -0
- data/test/emails/embedded_email_1.txt +8 -0
- data/test/emails/embedded_email_10.txt +42 -0
- data/test/emails/embedded_email_11.txt +5 -0
- data/test/emails/embedded_email_12.txt +18 -0
- data/test/emails/embedded_email_13.txt +14 -0
- data/test/emails/embedded_email_14.txt +16 -0
- data/test/emails/embedded_email_15.txt +9 -0
- data/test/emails/embedded_email_16.txt +16 -0
- data/test/emails/embedded_email_17.txt +38 -0
- data/test/emails/embedded_email_18.txt +7 -0
- data/test/emails/embedded_email_19.txt +13 -0
- data/test/emails/embedded_email_2.txt +16 -0
- data/test/emails/embedded_email_3.txt +24 -0
- data/test/emails/embedded_email_4.txt +19 -0
- data/test/emails/embedded_email_5.txt +5 -0
- data/test/emails/embedded_email_6.txt +11 -0
- data/test/emails/embedded_email_7.txt +20 -0
- data/test/emails/embedded_email_8.txt +5 -0
- data/test/emails/embedded_email_9.txt +5 -0
- data/test/emails/embedded_email_chinese.txt +7 -0
- data/test/emails/embedded_email_dutch_1.txt +13 -0
- data/test/emails/embedded_email_dutch_2.txt +62 -0
- data/test/emails/embedded_email_french_1.txt +12 -0
- data/test/emails/embedded_email_french_2.txt +21 -0
- data/test/emails/embedded_email_german_1.txt +26 -0
- data/test/emails/embedded_email_german_2.txt +6 -0
- data/test/emails/embedded_email_german_3.txt +10 -0
- data/test/emails/embedded_email_german_4.txt +18 -0
- data/test/emails/embedded_email_german_5.txt +23 -0
- data/test/emails/embedded_email_german_6.txt +14 -0
- data/test/emails/embedded_email_italian.txt +31 -0
- data/test/emails/embedded_email_norwegian.txt +11 -0
- data/test/emails/embedded_email_polish_1.txt +34 -0
- data/test/emails/embedded_email_polish_2.txt +11 -0
- data/test/emails/embedded_email_portuguese.txt +18 -0
- data/test/emails/embedded_email_quote_text.txt +10 -0
- data/test/emails/embedded_email_russian_1.txt +27 -0
- data/test/emails/embedded_email_russian_2.txt +26 -0
- data/test/emails/embedded_email_spanish_1.txt +41 -0
- data/test/emails/embedded_email_spanish_2.txt +12 -0
- data/test/emails/embedded_email_swedish.txt +20 -0
- data/test/emails/embedded_email_ukrainian.txt +19 -0
- data/test/emails/forwarded_apple.txt +17 -0
- data/test/emails/forwarded_gmail.txt +17 -0
- data/test/emails/forwarded_message.txt +9 -0
- data/test/emails/normalize_line_endings.txt +4 -0
- data/test/emails/quote_and_text.txt +3 -0
- data/test/emails/quote_only.txt +1 -0
- data/test/emails/retains_spaces_and_formatting.txt +14 -0
- data/test/emails/signatures.txt +33 -0
- data/test/emails/spam_1.txt +75 -0
- data/test/emails/spam_2.txt +174 -0
- data/test/emails/strip.txt +10 -0
- data/test/emails/text_only.txt +1 -0
- data/test/emails/usenet.txt +9 -0
- data/test/embedded/email_headers_1.txt +12 -0
- data/test/embedded/email_headers_2.txt +8 -0
- data/test/embedded/email_headers_3.txt +16 -0
- data/test/embedded/email_headers_4.txt +15 -0
- data/test/embedded/embedded_email_10.txt +15 -0
- data/test/embedded/embedded_email_german_3.txt +6 -0
- data/test/embedded/embedded_email_spanish_2.txt +9 -0
- data/test/embedded/forwarded_apple.txt +13 -0
- data/test/embedded/forwarded_gmail.txt +14 -0
- data/test/embedded/forwarded_message.txt +8 -0
- data/test/matchers/does_not_contain_embedded_email.txt +5 -0
- data/test/test_email_matcher.rb +17 -0
- data/test/test_email_reply_trimmer.rb +87 -0
- data/test/trimmed/delimiters.txt +3 -0
- data/test/trimmed/dual_embedded.txt +1 -0
- data/test/trimmed/email_headers_1.txt +1 -0
- data/test/trimmed/email_headers_2.txt +1 -0
- data/test/trimmed/email_headers_3.txt +1 -0
- data/test/trimmed/email_headers_4.txt +1 -0
- data/test/trimmed/email_headers_5.txt +11 -0
- data/test/trimmed/embedded_ception.txt +4 -0
- data/test/trimmed/embedded_email_1.txt +1 -0
- data/test/trimmed/embedded_email_10.txt +1 -0
- data/test/trimmed/embedded_email_11.txt +1 -0
- data/test/trimmed/embedded_email_12.txt +1 -0
- data/test/trimmed/embedded_email_13.txt +3 -0
- data/test/trimmed/embedded_email_14.txt +3 -0
- data/test/trimmed/embedded_email_15.txt +3 -0
- data/test/trimmed/embedded_email_16.txt +11 -0
- data/test/trimmed/embedded_email_17.txt +35 -0
- data/test/trimmed/embedded_email_18.txt +5 -0
- data/test/trimmed/embedded_email_19.txt +13 -0
- data/test/trimmed/embedded_email_2.txt +3 -0
- data/test/trimmed/embedded_email_3.txt +7 -0
- data/test/trimmed/embedded_email_4.txt +2 -0
- data/test/trimmed/embedded_email_5.txt +1 -0
- data/test/trimmed/embedded_email_6.txt +7 -0
- data/test/trimmed/embedded_email_7.txt +10 -0
- data/test/trimmed/embedded_email_8.txt +1 -0
- data/test/trimmed/embedded_email_9.txt +1 -0
- data/test/trimmed/embedded_email_chinese.txt +2 -0
- data/test/trimmed/embedded_email_dutch_1.txt +1 -0
- data/test/trimmed/embedded_email_dutch_2.txt +2 -0
- data/test/trimmed/embedded_email_french_1.txt +1 -0
- data/test/trimmed/embedded_email_french_2.txt +1 -0
- data/test/trimmed/embedded_email_german_1.txt +1 -0
- data/test/trimmed/embedded_email_german_2.txt +1 -0
- data/test/trimmed/embedded_email_german_3.txt +1 -0
- data/test/trimmed/embedded_email_german_4.txt +1 -0
- data/test/trimmed/embedded_email_german_5.txt +1 -0
- data/test/trimmed/embedded_email_german_6.txt +4 -0
- data/test/trimmed/embedded_email_italian.txt +1 -0
- data/test/trimmed/embedded_email_norwegian.txt +1 -0
- data/test/trimmed/embedded_email_polish_1.txt +1 -0
- data/test/trimmed/embedded_email_polish_2.txt +2 -0
- data/test/trimmed/embedded_email_portuguese.txt +2 -0
- data/test/trimmed/embedded_email_quote_text.txt +2 -0
- data/test/trimmed/embedded_email_russian_1.txt +1 -0
- data/test/trimmed/embedded_email_russian_2.txt +1 -0
- data/test/trimmed/embedded_email_spanish_1.txt +6 -0
- data/test/trimmed/embedded_email_spanish_2.txt +1 -0
- data/test/trimmed/embedded_email_swedish.txt +9 -0
- data/test/trimmed/embedded_email_ukrainian.txt +1 -0
- data/test/trimmed/forwarded_apple.txt +1 -0
- data/test/trimmed/forwarded_gmail.txt +1 -0
- data/test/trimmed/forwarded_message.txt +1 -0
- data/test/trimmed/normalize_line_endings.txt +4 -0
- data/test/trimmed/quote_and_text.txt +3 -0
- data/test/trimmed/quote_only.txt +1 -0
- data/test/trimmed/retains_spaces_and_formatting.txt +14 -0
- data/test/trimmed/signatures.txt +1 -0
- data/test/trimmed/spam_1.txt +0 -0
- data/test/trimmed/spam_2.txt +21 -0
- data/test/trimmed/strip.txt +1 -0
- data/test/trimmed/text_only.txt +1 -0
- data/test/trimmed/usenet.txt +1 -0
- metadata +275 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: dd04b62e18b2b1f82ad85786471685f6dc53c9675d2f7d7431966fd0bb518a79
|
4
|
+
data.tar.gz: ff797d745d30f3cc614dd8a5a76b669e1e4baa02dffd93a949523f0e7750ed00
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cc7c3c0a0956f7d36aea958cdbcb42992958fc59e85d0e0bfc401857c8779a38e41038fa753ced8f8a268542fa45f96cf2bd96d69a150a273cb1714c429d3797
|
7
|
+
data.tar.gz: badb11c1de342bca0146764c79272a8cfe9220e0376d3665df1ccd9fc2cee1a0b9ad783c1f99613b694ad2ac6184602271a9b037c4150cf6120be4f91881701b
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
# Specify your gem's dependencies in runger_email_reply_trimmer.gemspec
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem 'release_assistant', require: false, git: 'https://github.com/davidrunger/release_assistant'
|
10
|
+
end
|
11
|
+
|
12
|
+
group :development, :test do
|
13
|
+
gem 'minitest', '~> 5', require: false
|
14
|
+
gem 'rake', '~> 12', require: false
|
15
|
+
gem 'rubocop', require: false
|
16
|
+
gem 'runger_style', require: false
|
17
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/davidrunger/release_assistant
|
3
|
+
revision: a278e05c53c700b8946e5fed16c7286eacb963e3
|
4
|
+
specs:
|
5
|
+
release_assistant (0.3.3.alpha)
|
6
|
+
activesupport (>= 6, < 8)
|
7
|
+
colorize (~> 0.8)
|
8
|
+
memoist (~> 0.16)
|
9
|
+
slop (~> 4.8)
|
10
|
+
|
11
|
+
PATH
|
12
|
+
remote: .
|
13
|
+
specs:
|
14
|
+
runger_email_reply_trimmer (0.2.1)
|
15
|
+
|
16
|
+
GEM
|
17
|
+
remote: https://rubygems.org/
|
18
|
+
specs:
|
19
|
+
activesupport (7.0.4.3)
|
20
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
21
|
+
i18n (>= 1.6, < 2)
|
22
|
+
minitest (>= 5.1)
|
23
|
+
tzinfo (~> 2.0)
|
24
|
+
ast (2.4.2)
|
25
|
+
colorize (0.8.1)
|
26
|
+
concurrent-ruby (1.2.2)
|
27
|
+
i18n (1.13.0)
|
28
|
+
concurrent-ruby (~> 1.0)
|
29
|
+
json (2.6.3)
|
30
|
+
memoist (0.16.2)
|
31
|
+
minitest (5.18.0)
|
32
|
+
parallel (1.23.0)
|
33
|
+
parser (3.2.2.1)
|
34
|
+
ast (~> 2.4.1)
|
35
|
+
rainbow (3.1.1)
|
36
|
+
rake (12.3.3)
|
37
|
+
regexp_parser (2.8.0)
|
38
|
+
rexml (3.2.5)
|
39
|
+
rubocop (1.51.0)
|
40
|
+
json (~> 2.3)
|
41
|
+
parallel (~> 1.10)
|
42
|
+
parser (>= 3.2.0.0)
|
43
|
+
rainbow (>= 2.2.2, < 4.0)
|
44
|
+
regexp_parser (>= 1.8, < 3.0)
|
45
|
+
rexml (>= 3.2.5, < 4.0)
|
46
|
+
rubocop-ast (>= 1.28.0, < 2.0)
|
47
|
+
ruby-progressbar (~> 1.7)
|
48
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
49
|
+
rubocop-ast (1.28.1)
|
50
|
+
parser (>= 3.2.1.0)
|
51
|
+
ruby-progressbar (1.13.0)
|
52
|
+
runger_style (0.2.22)
|
53
|
+
rubocop (>= 1.38.0, < 2)
|
54
|
+
slop (4.10.1)
|
55
|
+
tzinfo (2.0.6)
|
56
|
+
concurrent-ruby (~> 1.0)
|
57
|
+
unicode-display_width (2.4.2)
|
58
|
+
|
59
|
+
PLATFORMS
|
60
|
+
x86_64-darwin-20
|
61
|
+
x86_64-linux
|
62
|
+
|
63
|
+
DEPENDENCIES
|
64
|
+
minitest (~> 5)
|
65
|
+
rake (~> 12)
|
66
|
+
release_assistant!
|
67
|
+
rubocop
|
68
|
+
runger_email_reply_trimmer!
|
69
|
+
runger_style
|
70
|
+
|
71
|
+
BUNDLED WITH
|
72
|
+
2.4.12
|
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) Discourse
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Runger Email Reply Trimmer
|
2
|
+
|
3
|
+
RungerEmailReplyTrimmer is a small library to trim replies from plain text email.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
To trim replies:
|
8
|
+
|
9
|
+
`trimmed_body = RungerEmailReplyTrimmer.trim(email_body)`
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
List the gem in your `Gemfile`:
|
14
|
+
|
15
|
+
```rb
|
16
|
+
gem 'runger_email_reply_trimmer'
|
17
|
+
```
|
18
|
+
|
19
|
+
## This is a fork
|
20
|
+
|
21
|
+
It was forked from https://github.com/discourse/email_reply_trimmer.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
5
|
+
|
6
|
+
def name
|
7
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
8
|
+
end
|
9
|
+
|
10
|
+
def version
|
11
|
+
@version ||= File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*['"](?'version'\d+\.\d+\.\d+)['"]/,
|
12
|
+
'version']
|
13
|
+
end
|
14
|
+
|
15
|
+
Rake::TestTask.new(:test)
|
16
|
+
|
17
|
+
task default: :test
|
data/bin/release
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'release' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'rubygems'
|
25
|
+
require 'bundler/setup'
|
26
|
+
|
27
|
+
load Gem.bin_path('release_assistant', 'release')
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DelimiterMatcher
|
4
|
+
module_function
|
5
|
+
|
6
|
+
DELIMITER_CHARACTERS = '-_,=+~#*ᐧ—'
|
7
|
+
DELIMITER_REGEX = /^[[:blank:]]*[#{Regexp.escape(DELIMITER_CHARACTERS)}]+[[:blank:]]*$/
|
8
|
+
|
9
|
+
def match?(line)
|
10
|
+
line =~ DELIMITER_REGEX
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EmailHeaderMatcher
|
4
|
+
module_function
|
5
|
+
|
6
|
+
EMAIL_HEADERS_WITH_DATE_MARKERS = [
|
7
|
+
# Norwegian
|
8
|
+
['Sendt'],
|
9
|
+
# English
|
10
|
+
['Sent', 'Date'],
|
11
|
+
# French
|
12
|
+
['Date', 'Le'],
|
13
|
+
# German
|
14
|
+
['Gesendet'],
|
15
|
+
# Portuguese
|
16
|
+
['Enviada em'],
|
17
|
+
# Spanish
|
18
|
+
['Enviado'],
|
19
|
+
# Spanish (Mexican)
|
20
|
+
['Fecha'],
|
21
|
+
# Italian
|
22
|
+
['Data'],
|
23
|
+
# Dutch
|
24
|
+
['Datum'],
|
25
|
+
# Swedish
|
26
|
+
['Skickat'],
|
27
|
+
# Chinese
|
28
|
+
['发送时间'],
|
29
|
+
].freeze
|
30
|
+
|
31
|
+
EMAIL_HEADERS_WITH_DATE_REGEXES =
|
32
|
+
EMAIL_HEADERS_WITH_DATE_MARKERS.map do |header|
|
33
|
+
/^[[:blank:]*]*(?:#{header.join("|")})[[:blank:]*]*:.*\d+/
|
34
|
+
end
|
35
|
+
|
36
|
+
EMAIL_HEADERS_WITH_TEXT_MARKERS = [
|
37
|
+
# Norwegian
|
38
|
+
['Fra', 'Til', 'Emne'],
|
39
|
+
# English
|
40
|
+
['From', 'To', 'Cc', 'Reply-To', 'Subject'],
|
41
|
+
# French
|
42
|
+
['De', 'Expéditeur', 'À', 'Destinataire', 'Répondre à', 'Objet'],
|
43
|
+
# German
|
44
|
+
['Von', 'An', 'Betreff'],
|
45
|
+
# Portuguese
|
46
|
+
['De', 'Para', 'Assunto'],
|
47
|
+
# Spanish
|
48
|
+
['De', 'Para', 'Asunto'],
|
49
|
+
# Italian
|
50
|
+
['Da', 'Risposta', 'A', 'Oggetto'],
|
51
|
+
# Dutch
|
52
|
+
['Van', 'Beantwoorden - Aan', 'Aan', 'Onderwerp'],
|
53
|
+
# Swedish
|
54
|
+
['Från', 'Till', 'Ämne'],
|
55
|
+
# Chinese
|
56
|
+
['发件人', '收件人', '主题'],
|
57
|
+
].freeze
|
58
|
+
|
59
|
+
EMAIL_HEADERS_WITH_TEXT_REGEXES =
|
60
|
+
EMAIL_HEADERS_WITH_TEXT_MARKERS.map do |header|
|
61
|
+
/^[[:blank:]*]*(?:#{header.join("|")})[[:blank:]*]*:.*[[:word:]]+/i
|
62
|
+
end
|
63
|
+
|
64
|
+
EMAIL_HEADER_REGEXES = [
|
65
|
+
EMAIL_HEADERS_WITH_DATE_REGEXES,
|
66
|
+
EMAIL_HEADERS_WITH_TEXT_REGEXES,
|
67
|
+
].flatten
|
68
|
+
|
69
|
+
def match?(line)
|
70
|
+
EMAIL_HEADER_REGEXES.any? { |r| line =~ r }
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EmbeddedEmailMatcher
|
4
|
+
module_function
|
5
|
+
|
6
|
+
# On Wed, Sep 25, 2013, at 03:57 PM, jorge_castro wrote:
|
7
|
+
# On Thursday, June 27, 2013, knwang via Discourse Meta wrote:
|
8
|
+
# On Wed, 2015-12-02 at 13:58 +0000, Tom Newsom wrote:
|
9
|
+
# On 10/12/15 12:30, Jeff Atwood wrote:
|
10
|
+
# ---- On Tue, 22 Dec 2015 14:17:36 +0530 Sam Saffron<info@discourse.org> wrote ----
|
11
|
+
# Op 24 aug. 2013 om 16:48 heeft ven88 via Discourse Meta <info@discourse.org> het volgende geschreven:
|
12
|
+
# Le 4 janv. 2016 19:03, "Neil Lalonde" <info@discourse.org> a écrit :
|
13
|
+
# Dnia 14 lip 2015 o godz. 00:25 Michael Downey <info@discourse.org> napisał(a):
|
14
|
+
# Em seg, 27 de jul de 2015 17:13, Neil Lalonde <info@discourse.org> escreveu:
|
15
|
+
# El jueves, 21 de noviembre de 2013, codinghorror escribió:
|
16
|
+
# At 6/16/2016 08:32 PM, you wrote:
|
17
|
+
ON_DATE_SOMEONE_WROTE_REGEXES = [
|
18
|
+
# Chinese
|
19
|
+
/^[[:blank:]<>-]*在 (?:(?!\b(?>在|写道)\b).)+?写道[[:blank:].:>-]*$/im,
|
20
|
+
# Dutch
|
21
|
+
/^[[:blank:]<>-]*Op (?:(?!\b(?>Op|het\svolgende\sgeschreven|schreef)\b).)+?(het\svolgende\sgeschreven|schreef[^:]+)[[:blank:].:>-]*$/im,
|
22
|
+
# English
|
23
|
+
/^[[:blank:]<>-]*In message (?:(?!\b(?>In message|writes)\b).)+?writes[[:blank:].:>-]*$/im,
|
24
|
+
/^[[:blank:]<>-]*(On|At) (?:(?!\b(?>On|wrote|writes|says|said)\b).)+?(wrote|writes|says|said)[[:blank:].:>-]*$/im,
|
25
|
+
# French
|
26
|
+
/^[[:blank:]<>-]*Le (?:(?!\b(?>Le|nous\sa\sdit|a\s+écrit)\b).)+?(nous\sa\sdit|a\s+écrit)[[:blank:].:>-]*$/im,
|
27
|
+
# German
|
28
|
+
/^[[:blank:]<>-]*Am (?:(?!\b(?>Am|schrieben\sSie)\b).)+?schrieben\sSie[[:blank:].:>-]*$/im,
|
29
|
+
/^[[:blank:]<>-]*Am (?:(?!\b(?>Am|geschrieben)\b).)+?(geschrieben|schrieb[^:]+)[[:blank:].:>-]*$/im,
|
30
|
+
# Italian
|
31
|
+
/^[[:blank:]<>-]*Il (?:(?!\b(?>Il|ha\sscritto)\b).)+?ha\sscritto[[:blank:].:>-]*$/im,
|
32
|
+
# Polish
|
33
|
+
/^[[:blank:]<>-]*(Dnia|Dňa) (?:(?!\b(?>Dnia|Dňa|napisał)\b).)+?napisał(\(a\))?[[:blank:].:>-]*$/im,
|
34
|
+
# Portuguese
|
35
|
+
/^[[:blank:]<>-]*Em (?:(?!\b(?>Em|escreveu)\b).)+?escreveu[[:blank:].:>-]*$/im,
|
36
|
+
# Spanish
|
37
|
+
/^[[:blank:]<>-]*El (?:(?!\b(?>El|escribió)\b).)+?escribió[[:blank:].:>-]*$/im,
|
38
|
+
].freeze
|
39
|
+
|
40
|
+
# Op 10 dec. 2015 18:35 schreef "Arpit Jalan" <info@discourse.org>:
|
41
|
+
# Am 18.09.2013 um 16:24 schrieb codinghorror <info@discourse.org>:
|
42
|
+
# Den 15. jun. 2016 kl. 20.42 skrev Jeff Atwood <info@discourse.org>:
|
43
|
+
# søn. 30. apr. 2017 kl. 00.26 skrev David Taylor <meta@discoursemail.com>:
|
44
|
+
ON_DATE_WROTE_SOMEONE_MARKERS = [
|
45
|
+
# Dutch
|
46
|
+
['Op', 'schreef'],
|
47
|
+
# German
|
48
|
+
['Am', 'schrieb'],
|
49
|
+
# Norwegian
|
50
|
+
['Den', 'skrev'],
|
51
|
+
# Dutch
|
52
|
+
['søn.', 'skrev'],
|
53
|
+
].freeze
|
54
|
+
|
55
|
+
ON_DATE_WROTE_SOMEONE_REGEXES =
|
56
|
+
ON_DATE_WROTE_SOMEONE_MARKERS.map do |on, wrote|
|
57
|
+
/^[[:blank:]>]*#{on}\s.+\s#{wrote}\s[^:]+:/
|
58
|
+
end
|
59
|
+
|
60
|
+
# суббота, 14 марта 2015 г. пользователь etewiah написал:
|
61
|
+
# 23 mar 2017 21:25 "Neil Lalonde" <meta@discoursemail.com> napisał(a):
|
62
|
+
# 30 серп. 2016 р. 20:45 "Arpit" no-reply@example.com пише:
|
63
|
+
DATE_SOMEONE_WROTE_MARKERS = [
|
64
|
+
# Russian
|
65
|
+
['пользователь', 'написал'],
|
66
|
+
# Polish
|
67
|
+
['', 'napisał\\(a\\)'],
|
68
|
+
# Ukrainian
|
69
|
+
['', 'пише'],
|
70
|
+
].freeze
|
71
|
+
|
72
|
+
DATE_SOMEONE_WROTE_REGEXES =
|
73
|
+
DATE_SOMEONE_WROTE_MARKERS.map do |user, wrote|
|
74
|
+
if user.empty?
|
75
|
+
/\d{4}.{1,80}\n?.{0,80}?#{wrote}:/
|
76
|
+
else
|
77
|
+
/\d{4}.{1,80}#{user}.{0,80}\n?.{0,80}?#{wrote}:/
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Max Mustermann <try_discourse@discoursemail.com> schrieb am Fr., 28. Apr. 2017 um 11:53 Uhr:
|
82
|
+
SOMEONE_WROTE_ON_DATE_REGEXES = [
|
83
|
+
# English
|
84
|
+
/^.+\bwrote\b[[:space:]]+\bon\b.+[^:]+:/,
|
85
|
+
# German
|
86
|
+
/^.+\bschrieb\b[[:space:]]+\bam\b.+[^:]+:/,
|
87
|
+
].freeze
|
88
|
+
|
89
|
+
# 2016-03-03 17:21 GMT+01:00 Some One
|
90
|
+
ISO_DATE_SOMEONE_REGEX = /^[[:blank:]>]*20\d\d-\d\d-\d\d \d\d:\d\d GMT\+\d\d:\d\d [\w[:blank:]]+$/
|
91
|
+
|
92
|
+
# 2015-10-18 0:17 GMT+03:00 Matt Palmer <info@discourse.org>:
|
93
|
+
# 2013/10/2 camilohollanda <info@discourse.org>
|
94
|
+
# вт, 5 янв. 2016 г. в 23:39, Erlend Sogge Heggen <info@discourse.org>:
|
95
|
+
# ср, 1 апр. 2015, 18:29, Denis Didkovsky <info@discourse.org>:
|
96
|
+
DATE_SOMEONE_EMAIL_REGEX = /\d{4}.{1,80}\s?<[^@<>]+@[^@<>.]+\.[^@<>]+>:?$/
|
97
|
+
|
98
|
+
# codinghorror via Discourse Meta wrote:
|
99
|
+
# codinghorror via Discourse Meta <info@discourse.org> schrieb:
|
100
|
+
SOMEONE_VIA_SOMETHING_WROTE_MARKERS = [
|
101
|
+
# English
|
102
|
+
'wrote',
|
103
|
+
# German
|
104
|
+
'schrieb',
|
105
|
+
].freeze
|
106
|
+
|
107
|
+
SOMEONE_VIA_SOMETHING_WROTE_REGEXES =
|
108
|
+
SOMEONE_VIA_SOMETHING_WROTE_MARKERS.map do |wrote|
|
109
|
+
/^.+ via .+ #{wrote}:?[[:blank:]]*$/
|
110
|
+
end
|
111
|
+
|
112
|
+
# Some One <info@discourse.org> wrote:
|
113
|
+
# Gavin Sinclair (gsinclair@soyabean.com.au) wrote:
|
114
|
+
SOMEONE_EMAIL_WROTE_REGEX = /^.+\b[\w.+-]+@[\w.-]+\.\w{2,}\b.+wrote:?$/
|
115
|
+
|
116
|
+
# Posted by mpalmer on 01/21/2016
|
117
|
+
POSTED_BY_SOMEONE_ON_DATE_REGEX = /^[[:blank:]>]*Posted by .+ on \d{2}\/\d{2}\/\d{4}$/i
|
118
|
+
|
119
|
+
# Begin forwarded message:
|
120
|
+
# Reply Message
|
121
|
+
# ----- Forwarded Message -----
|
122
|
+
# ----- Original Message -----
|
123
|
+
# -----Original Message-----
|
124
|
+
# *----- Original Message -----*
|
125
|
+
# ----- Reply message -----
|
126
|
+
# ------------------ 原始邮件 ------------------
|
127
|
+
FORWARDED_EMAIL_REGEXES = [
|
128
|
+
# English
|
129
|
+
/^[[:blank:]>]*Begin forwarded message:/i,
|
130
|
+
/^[[:blank:]>*]*-{2,}[[:blank:]]*(Forwarded|Original|Reply) Message[[:blank:]]*-{2,}/i,
|
131
|
+
# French
|
132
|
+
/^[[:blank:]>]*Début du message transféré :/i,
|
133
|
+
/^[[:blank:]>*]*-{2,}[[:blank:]]*Message transféré[[:blank:]]*-{2,}/i,
|
134
|
+
# German
|
135
|
+
/^[[:blank:]>*]*-{2,}[[:blank:]]*Ursprüngliche Nachricht[[:blank:]]*-{2,}/i,
|
136
|
+
# Spanish
|
137
|
+
/^[[:blank:]>*]*-{2,}[[:blank:]]*Mensaje original[[:blank:]]*-{2,}/i,
|
138
|
+
# Chinese
|
139
|
+
/^[[:blank:]>*]*-{2,}[[:blank:]]*原始邮件[[:blank:]]*-{2,}/i,
|
140
|
+
].freeze
|
141
|
+
|
142
|
+
EMBEDDED_REGEXES = [
|
143
|
+
ON_DATE_SOMEONE_WROTE_REGEXES,
|
144
|
+
ON_DATE_WROTE_SOMEONE_REGEXES,
|
145
|
+
DATE_SOMEONE_WROTE_REGEXES,
|
146
|
+
DATE_SOMEONE_EMAIL_REGEX,
|
147
|
+
SOMEONE_WROTE_ON_DATE_REGEXES,
|
148
|
+
ISO_DATE_SOMEONE_REGEX,
|
149
|
+
SOMEONE_VIA_SOMETHING_WROTE_REGEXES,
|
150
|
+
SOMEONE_EMAIL_WROTE_REGEX,
|
151
|
+
POSTED_BY_SOMEONE_ON_DATE_REGEX,
|
152
|
+
FORWARDED_EMAIL_REGEXES,
|
153
|
+
].flatten
|
154
|
+
|
155
|
+
def match?(line)
|
156
|
+
EMBEDDED_REGEXES.any? { |r| line =~ r }
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SignatureMatcher
|
4
|
+
module_function
|
5
|
+
|
6
|
+
# Envoyé depuis mon iPhone
|
7
|
+
# Von meinem Mobilgerät gesendet
|
8
|
+
# Diese Nachricht wurde von meinem Android-Mobiltelefon mit K-9 Mail gesendet.
|
9
|
+
# Nik from mobile
|
10
|
+
# From My Iphone 6
|
11
|
+
# Sent via mobile
|
12
|
+
# Sent with Airmail
|
13
|
+
# Sent from Windows Mail
|
14
|
+
# Sent from my TI-85
|
15
|
+
# <<sent by galaxy>>
|
16
|
+
# (sent from a phone)
|
17
|
+
# (Sent from mobile device)
|
18
|
+
# 從我的 iPhone 傳送
|
19
|
+
SIGNATURE_REGEXES = [
|
20
|
+
# Chinese
|
21
|
+
/^[[:blank:]]*從我的 iPhone 傳送/i,
|
22
|
+
# English
|
23
|
+
/^[[:blank:]]*[[:word:]]+ from mobile/i,
|
24
|
+
/^[[:blank:]]*[(<]*Sent (from|via|with|by) .+[)>]*/i,
|
25
|
+
/^[[:blank:]]*From my .{1,20}/i,
|
26
|
+
/^[[:blank:]]*Get Outlook for /i,
|
27
|
+
# French
|
28
|
+
/^[[:blank:]]*Envoyé depuis (mon|Yahoo Mail)/i,
|
29
|
+
# German
|
30
|
+
/^[[:blank:]]*Von meinem .+ gesendet/i,
|
31
|
+
/^[[:blank:]]*Diese Nachricht wurde von .+ gesendet/i,
|
32
|
+
# Italian
|
33
|
+
/^[[:blank:]]*Inviato da /i,
|
34
|
+
# Norwegian
|
35
|
+
/^[[:blank:]]*Sendt fra min /i,
|
36
|
+
# Portuguese
|
37
|
+
/^[[:blank:]]*Enviado do meu /i,
|
38
|
+
# Spanish
|
39
|
+
/^[[:blank:]]*Enviado desde mi /i,
|
40
|
+
# Dutch
|
41
|
+
/^[[:blank:]]*Verzonden met /i,
|
42
|
+
/^[[:blank:]]*Verstuurd vanaf mijn /i,
|
43
|
+
# Swedish
|
44
|
+
/^[[:blank:]]*från min /i,
|
45
|
+
].freeze
|
46
|
+
|
47
|
+
def match?(line)
|
48
|
+
# remove any markdown links
|
49
|
+
stripped = line.gsub(/\[([^\]]+)\]\([^)]+\)/) { ::Regexp.last_match(1) }
|
50
|
+
SIGNATURE_REGEXES.any? { |r| stripped =~ r }
|
51
|
+
end
|
52
|
+
end
|