email_reply_trimmer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +9 -0
  3. data/README.md +21 -0
  4. data/Rakefile +12 -0
  5. data/email_reply_trimmer.gemspec +20 -0
  6. data/lib/email_reply_trimmer/delimiter_matcher.rb +10 -0
  7. data/lib/email_reply_trimmer/email_header_matcher.rb +46 -0
  8. data/lib/email_reply_trimmer/embedded_email_matcher.rb +108 -0
  9. data/lib/email_reply_trimmer/empty_line_matcher.rb +7 -0
  10. data/lib/email_reply_trimmer/quote_matcher.rb +7 -0
  11. data/lib/email_reply_trimmer/signature_matcher.rb +33 -0
  12. data/lib/email_reply_trimmer.rb +100 -0
  13. data/test/emails/delimiters.txt +14 -0
  14. data/test/emails/email_headers_1.txt +17 -0
  15. data/test/emails/email_headers_2.txt +10 -0
  16. data/test/emails/embedded_email_1.txt +8 -0
  17. data/test/emails/embedded_email_2.txt +16 -0
  18. data/test/emails/embedded_email_3.txt +24 -0
  19. data/test/emails/embedded_email_4.txt +19 -0
  20. data/test/emails/embedded_email_5.txt +5 -0
  21. data/test/emails/embedded_email_6.txt +11 -0
  22. data/test/emails/embedded_email_7.txt +20 -0
  23. data/test/emails/embedded_email_8.txt +5 -0
  24. data/test/emails/embedded_email_dutch_1.txt +13 -0
  25. data/test/emails/embedded_email_dutch_2.txt +62 -0
  26. data/test/emails/embedded_email_french.txt +12 -0
  27. data/test/emails/embedded_email_german.txt +26 -0
  28. data/test/emails/embedded_email_polish.txt +34 -0
  29. data/test/emails/embedded_email_portuguese.txt +18 -0
  30. data/test/emails/embedded_email_quote_text.txt +10 -0
  31. data/test/emails/embedded_email_russian.txt +27 -0
  32. data/test/emails/embedded_email_spanish.txt +41 -0
  33. data/test/emails/forwarded_message.txt +9 -0
  34. data/test/emails/normalize_line_endings.txt +4 -0
  35. data/test/emails/quote_and_text.txt +3 -0
  36. data/test/emails/quote_only.txt +1 -0
  37. data/test/emails/retains_spaces_and_formatting.txt +14 -0
  38. data/test/emails/signatures.txt +27 -0
  39. data/test/emails/strip.txt +10 -0
  40. data/test/emails/text_only.txt +1 -0
  41. data/test/replies/delimiters.txt +3 -0
  42. data/test/replies/email_headers_1.txt +1 -0
  43. data/test/replies/email_headers_2.txt +1 -0
  44. data/test/replies/embedded_email_1.txt +1 -0
  45. data/test/replies/embedded_email_2.txt +3 -0
  46. data/test/replies/embedded_email_3.txt +7 -0
  47. data/test/replies/embedded_email_4.txt +2 -0
  48. data/test/replies/embedded_email_5.txt +1 -0
  49. data/test/replies/embedded_email_6.txt +7 -0
  50. data/test/replies/embedded_email_7.txt +19 -0
  51. data/test/replies/embedded_email_8.txt +1 -0
  52. data/test/replies/embedded_email_dutch_1.txt +1 -0
  53. data/test/replies/embedded_email_dutch_2.txt +2 -0
  54. data/test/replies/embedded_email_french.txt +1 -0
  55. data/test/replies/embedded_email_german.txt +1 -0
  56. data/test/replies/embedded_email_polish.txt +3 -0
  57. data/test/replies/embedded_email_portuguese.txt +2 -0
  58. data/test/replies/embedded_email_quote_text.txt +7 -0
  59. data/test/replies/embedded_email_russian.txt +1 -0
  60. data/test/replies/embedded_email_spanish.txt +6 -0
  61. data/test/replies/forwarded_message.txt +1 -0
  62. data/test/replies/normalize_line_endings.txt +4 -0
  63. data/test/replies/quote_and_text.txt +3 -0
  64. data/test/replies/quote_only.txt +1 -0
  65. data/test/replies/retains_spaces_and_formatting.txt +14 -0
  66. data/test/replies/signatures.txt +1 -0
  67. data/test/replies/strip.txt +1 -0
  68. data/test/replies/text_only.txt +1 -0
  69. data/test/test_email_reply_trimmer.rb +33 -0
  70. metadata +114 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7e62f9968467e01fa3a5889f8be9cf71de984d48
4
+ data.tar.gz: 0a04448f2c487e2b8086e511d82106f5392cdd8a
5
+ SHA512:
6
+ metadata.gz: 76db5365d1c3ae729a862ed55f4f704c529afaf8e25b925865ddb60967ff0c3ca36e69ce95c414b7c01609b1cd4ae42b09299f14cebc521fe84d78ca336972dc
7
+ data.tar.gz: 637c4cbf1df229ef073786d527a0d501013144c3e618b499309e4701b994b9a5fd917a032e2ef744e69a5800be83b734cd056aaef418ac544ab060625d0b5059
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
+ # Discourse Email Reply Trimmer
2
+
3
+ EmailReplyTrimmer is a small library to trim replies from plain text email.
4
+
5
+ ## Usage
6
+
7
+ To trim replies:
8
+
9
+ `trimmed_body = EmailReplyTrimmer.trim(email_body)`
10
+
11
+ ## Installation
12
+
13
+ Get it from [GitHub](https://github.com/discourse/email_reply_trimmer).
14
+
15
+ Run `rake` to run the tests.
16
+
17
+ ## Inspirations
18
+
19
+ - [GitHub's Email Reply Parser](https://github.com/github/email_reply_parser)
20
+ - [MailGun's Talon](https://github.com/mailgun/talon)
21
+ - [Vitor R. Carvalho's Learning to Extract Signature and Reply Lines from Email](http://www.cs.cmu.edu/~vitor/papers/sigFilePaper_finalversion.pdf)
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ def name
2
+ @name ||= Dir["*.gemspec"].first.split(".").first
3
+ end
4
+
5
+ def version
6
+ @version ||= File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*['"](?'version'\d+\.\d+\.\d+)['"]/, "version"]
7
+ end
8
+
9
+ task :default => :test
10
+
11
+ require "rake/testtask"
12
+ Rake::TestTask.new(:test)
@@ -0,0 +1,20 @@
1
+ require_relative "lib/email_reply_trimmer"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "email_reply_trimmer"
5
+ s.version = EmailReplyTrimmer::VERSION
6
+ s.date = Time.now.strftime('%Y-%m-%d')
7
+
8
+ s.summary = "Library to trim replies from plain text email."
9
+ s.description = "EmailReplyTrimmer is a small library to trim replies from plain text email."
10
+
11
+ s.authors = ["Régis Hanol"]
12
+ s.email = ["regis+rubygems@hanol.fr"]
13
+
14
+ s.homepage = "https://github.com/discourse/email_reply_trimmer"
15
+ s.license = "MIT"
16
+
17
+ s.require_paths = ["lib"]
18
+ s.files = Dir["**/*"].reject { |path| File.directory?(path) }
19
+ s.test_files = s.files.select { |path| path =~ /^test\/.+_test\.rb$/ }
20
+ end
@@ -0,0 +1,10 @@
1
+ class DelimiterMatcher
2
+
3
+ DELIMITER_CHARACTERS ||= ['-', '_', '=', '+','~', '#', '*', 'ᐧ']
4
+ DELIMITER_REGEX ||= /^[[:space:]]*[#{Regexp.escape(DELIMITER_CHARACTERS.join)}]+[[:space:]]*$/
5
+
6
+ def self.match?(line)
7
+ line =~ DELIMITER_REGEX
8
+ end
9
+
10
+ end
@@ -0,0 +1,46 @@
1
+ class EmailHeaderMatcher
2
+
3
+ EMAIL_HEADERS_WITH_DATE_MARKERS = [
4
+ # Dutch
5
+ ["Sendt"],
6
+ # English
7
+ ["Sent"],
8
+ # French
9
+ ["Date"],
10
+ # Portuguese
11
+ ["Enviada em"],
12
+ # Spanish (Mexican)
13
+ ["Fecha"],
14
+ ]
15
+
16
+ EMAIL_HEADERS_WITH_DATE_REGEXES = EMAIL_HEADERS_WITH_DATE_MARKERS.map do |header|
17
+ /^[[:space:]\*]*(?:#{header.join("|")})[[:space:]\*]*:.*\d+/
18
+ end
19
+
20
+ EMAIL_HEADERS_WITH_TEXT_MARKERS = [
21
+ # Dutch
22
+ ["Fra", "Til", "Emne"],
23
+ # English
24
+ ["From", "To", "Cc", "Reply-To", "Subject"],
25
+ # French
26
+ ["De", "À", "Répondre à", "Objet"],
27
+ # Portuguese
28
+ ["De", "Para", "Assunto"],
29
+ # Spanish (Mexican)
30
+ ["De", "Para", "Asunto"],
31
+ ]
32
+
33
+ EMAIL_HEADERS_WITH_TEXT_REGEXES = EMAIL_HEADERS_WITH_TEXT_MARKERS.map do |header|
34
+ /^[[:space:]\*]*(?:#{header.join("|")})[[:space:]\*]*:.*[[:word:]]+/
35
+ end
36
+
37
+ EMAIL_HEADER_REGEXES = [
38
+ EMAIL_HEADERS_WITH_DATE_REGEXES,
39
+ EMAIL_HEADERS_WITH_TEXT_REGEXES,
40
+ ].flatten
41
+
42
+ def self.match?(line)
43
+ EMAIL_HEADER_REGEXES.any? { |r| line =~ r }
44
+ end
45
+
46
+ end
@@ -0,0 +1,108 @@
1
+ class EmbeddedEmailMatcher
2
+
3
+ # On Wed, Sep 25, 2013, at 03:57 PM, jorge_castro wrote:
4
+ # On Thursday, June 27, 2013, knwang via Discourse Meta wrote:
5
+ # On Wed, 2015-12-02 at 13:58 +0000, Tom Newsom wrote:
6
+ # On 10/12/15 12:30, Jeff Atwood wrote:
7
+ # ---- On Tue, 22 Dec 2015 14:17:36 +0530 Sam Saffron<info@discourse.org> wrote ----
8
+ # Op 24 aug. 2013 om 16:48 heeft ven88 via Discourse Meta <info@discourse.org> het volgende geschreven:
9
+ # Le 4 janv. 2016 19:03, "Neil Lalonde" <info@discourse.org> a écrit :
10
+ # Dnia 14 lip 2015 o godz. 00:25 Michael Downey <info@discourse.org> napisał(a):
11
+ # Em seg, 27 de jul de 2015 17:13, Neil Lalonde <info@discourse.org> escreveu:
12
+ # El jueves, 21 de noviembre de 2013, codinghorror escribió:
13
+ ON_DATE_SOMEONE_WROTE_MARKERS = [
14
+ # Dutch
15
+ ["Op","het volgende geschreven"],
16
+ # English
17
+ ["On", "wrote"],
18
+ # French
19
+ ["Le", "a écrit "],
20
+ # Polish
21
+ ["Dnia", "napisał\\(a\\)"],
22
+ # Portuguese
23
+ ["Em", "escreveu"],
24
+ # Spanish
25
+ ["El", "escribió"],
26
+ ]
27
+
28
+ ON_DATE_SOMEONE_WROTE_REGEXES = ON_DATE_SOMEONE_WROTE_MARKERS.map do |on, wrote|
29
+ wrote.gsub!(" ", "[[:space:]]") # the "wrote" part might span over multiple lines
30
+ /^([ >\t\-]*#{on}\s(?:(?!#{on}\s|#{wrote}:?)[\s\S])*#{wrote}:?[ \t\-]*)$/m
31
+ end
32
+
33
+ # Op 10 dec. 2015 18:35 schreef "Arpit Jalan" <info@discourse.org>:
34
+ # Am 18.09.2013 um 16:24 schrieb codinghorror <info@discourse.org>:
35
+ ON_DATE_WROTE_SOMEONE_MARKERS = [
36
+ # Dutch
37
+ ["Op", "schreef"],
38
+ # German
39
+ ["Am", "schrieb"],
40
+ ]
41
+
42
+ ON_DATE_WROTE_SOMEONE_REGEXES = ON_DATE_WROTE_SOMEONE_MARKERS.map do |on, wrote|
43
+ /^[[:space:]]*#{on}\s.+\s#{wrote}\s[^:]+:/
44
+ end
45
+
46
+ # суббота, 14 марта 2015 г. пользователь etewiah написал:
47
+ DATE_SOMEONE_WROTE_MARKERS = [
48
+ # Russian
49
+ ["пользователь", "написал"],
50
+ ]
51
+
52
+ DATE_SOMEONE_WROTE_REGEXES = DATE_SOMEONE_WROTE_MARKERS.map do |user, wrote|
53
+ /[[:space:]]*.+#{user}.+#{wrote}:/
54
+ end
55
+
56
+ # 2015-10-18 0:17 GMT+03:00 Matt Palmer <info@discourse.org>:
57
+ # 2013/10/2 camilohollanda <info@discourse.org>
58
+ # вт, 5 янв. 2016 г. в 23:39, Erlend Sogge Heggen <info@discourse.org>:
59
+ # ср, 1 апр. 2015, 18:29, Denis Didkovsky <info@discourse.org>:
60
+ DATE_SOMEONE_EMAIL_REGEX = /^[[:space:]]*.*\d+.+<.+@.+\..+>:?/
61
+
62
+ # codinghorror via Discourse Meta wrote:
63
+ # codinghorror via Discourse Meta <info@discourse.org> schrieb:
64
+ SOMEONE_VIA_SOMETHING_WROTE_MARKERS = [
65
+ # English
66
+ "wrote",
67
+ # German
68
+ "schrieb",
69
+ ]
70
+
71
+ SOMEONE_VIA_SOMETHING_WROTE_REGEXES = SOMEONE_VIA_SOMETHING_WROTE_MARKERS.map do |wrote|
72
+ /^[[:space:]]*.+ via .+ #{wrote}:?[[:space:]]*$/
73
+ end
74
+
75
+ # Some One <info@discourse.org> wrote:
76
+ SOMEONE_EMAIL_WROTE_REGEX = /^[[:space:]]*.+ <.+@.+\..+> wrote:?/
77
+
78
+ # Posted by mpalmer on 01/21/2016
79
+ POSTED_BY_SOMEONE_ON_DATE_REGEX = /^[[:space:]]*Posted by .+ on \d{2}\/\d{2}\/\d{4}$/i
80
+
81
+ # Begin forwarded message:
82
+ # Reply Message
83
+ # ----- Forwarded Message -----
84
+ # ----- Original Message -----
85
+ # -----Original Message-----
86
+ FORWARDED_EMAIL_REGEXES = [
87
+ # English
88
+ /^[[:space:]]*Begin forwarded message:/i,
89
+ /^[[:space:]]*Reply message/i,
90
+ /^[[:space:]]*-{2,}[[:space:]]*(Forwarded|Original) Message[[:space:]]*-{2,}/i
91
+ ]
92
+
93
+ EMBEDDED_REGEXES = [
94
+ ON_DATE_SOMEONE_WROTE_REGEXES,
95
+ ON_DATE_WROTE_SOMEONE_REGEXES,
96
+ DATE_SOMEONE_WROTE_REGEXES,
97
+ DATE_SOMEONE_EMAIL_REGEX,
98
+ SOMEONE_VIA_SOMETHING_WROTE_REGEXES,
99
+ SOMEONE_EMAIL_WROTE_REGEX,
100
+ POSTED_BY_SOMEONE_ON_DATE_REGEX,
101
+ FORWARDED_EMAIL_REGEXES,
102
+ ].flatten
103
+
104
+ def self.match?(line)
105
+ EMBEDDED_REGEXES.any? { |r| line =~ r }
106
+ end
107
+
108
+ end
@@ -0,0 +1,7 @@
1
+ class EmptyLineMatcher
2
+
3
+ def self.match?(line)
4
+ line =~ /^[[:space:]]*$/
5
+ end
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ class QuoteMatcher
2
+
3
+ def self.match?(line)
4
+ line =~ /^[[:space:]]*>/
5
+ end
6
+
7
+ end
@@ -0,0 +1,33 @@
1
+ class SignatureMatcher
2
+
3
+ # Envoyé depuis mon iPhone
4
+ # Von meinem Mobilgerät gesendet
5
+ # Diese Nachricht wurde von meinem Android-Mobiltelefon mit K-9 Mail gesendet.
6
+ # Nik from mobile
7
+ # From My Iphone 6
8
+ # Sent via mobile
9
+ # Sent with Airmail
10
+ # Sent from Windows Mail
11
+ # Sent from my TI-85
12
+ # <<sent by galaxy>>
13
+ # (sent from a phone)
14
+ # (Sent from mobile device)
15
+ SIGNATURE_REGEXES = [
16
+ # English
17
+ /^[[:space:]]*[[:word:]]+ from mobile/i,
18
+ /^[[:space:]]*sent (?:from|via|with|by) .+/i,
19
+ /^[[:space:]]*\(sent (?:from|via|with|by) .+\)/i,
20
+ /^[[:space:]]*<<sent (?:from|via|with|by) .+>>/i,
21
+ /^[[:space:]]*from my .{1,20}/i, # don't match too much
22
+ # French
23
+ /^[[:space:]]*Envoyé depuis mon .+/i,
24
+ # German
25
+ /^[[:space:]]*Von meinem Mobilgerät gesendet/i,
26
+ /^[[:space:]]*Diese Nachricht wurde von .+ gesendet/i,
27
+ ]
28
+
29
+ def self.match?(line)
30
+ SIGNATURE_REGEXES.any? { |r| line =~ r }
31
+ end
32
+
33
+ end
@@ -0,0 +1,100 @@
1
+ require_relative "email_reply_trimmer/empty_line_matcher"
2
+ require_relative "email_reply_trimmer/delimiter_matcher"
3
+ require_relative "email_reply_trimmer/signature_matcher"
4
+ require_relative "email_reply_trimmer/embedded_email_matcher"
5
+ require_relative "email_reply_trimmer/email_header_matcher"
6
+ require_relative "email_reply_trimmer/quote_matcher"
7
+
8
+ class EmailReplyTrimmer
9
+ VERSION = "0.0.1"
10
+
11
+ DELIMITER = "d"
12
+ EMBEDDED = "b"
13
+ EMPTY = "e"
14
+ EMAIL_HEADER = "h"
15
+ QUOTE = "q"
16
+ SIGNATURE = "s"
17
+ TEXT = "t"
18
+
19
+ def self.identify_line_content(line)
20
+ return EMPTY if EmptyLineMatcher.match?(line)
21
+ return DELIMITER if DelimiterMatcher.match?(line)
22
+ return SIGNATURE if SignatureMatcher.match?(line)
23
+ return EMBEDDED if EmbeddedEmailMatcher.match?(line)
24
+ return EMAIL_HEADER if EmailHeaderMatcher.match?(line)
25
+ return QUOTE if QuoteMatcher.match?(line)
26
+ return TEXT
27
+ end
28
+
29
+ def self.trim(text)
30
+ # normalize line endings
31
+ text = text.gsub!(/\r*\n/, "\n")
32
+
33
+ # fix embedded email markers that might span over multiple lines
34
+ EmbeddedEmailMatcher::ON_DATE_SOMEONE_WROTE_REGEXES.each do |r|
35
+ next unless text =~ r
36
+ text.gsub!($1, $1.gsub(/\n[[:space:]>\-]*/, " "))
37
+ end
38
+
39
+ # from now on, we'll work on a line-by-line basis
40
+ lines = text.split("\n")
41
+
42
+ # identify content of each lines
43
+ pattern = lines.map { |l| identify_line_content(l) }.join
44
+
45
+ # remove all signatures & delimiters
46
+ while pattern =~ /[ds]/
47
+ index = pattern =~ /[ds]/
48
+ pattern.slice!(index)
49
+ lines.slice!(index)
50
+ end
51
+
52
+ # if there is an embedded email marker, followed only by a quote and eventually some text
53
+ # then take everything up to that marker
54
+ if pattern =~ /t[eq]*b[eq]*[et]*$/
55
+ index = pattern =~ /t[eq]*b[eq]*[et]*$/
56
+ pattern = pattern[0..index]
57
+ lines = lines[0..index]
58
+ end
59
+
60
+ # if there still are some embedded email markers, just empty them
61
+ while pattern =~ /b/
62
+ index = pattern =~ /b/
63
+ pattern[index] = "e"
64
+ lines[index] = ""
65
+ end
66
+
67
+ # fix email headers when they span over multiple lines
68
+ if pattern =~ /hh[ht]+e/
69
+ index = pattern =~ /hh[ht]+e/
70
+ size = pattern[/hh[ht]+/].size
71
+ size.times.each { |s| pattern[index + s] = EMAIL_HEADER }
72
+ end
73
+
74
+ # if there are at least 3 consecutive email headers, take everything up to
75
+ # these headers
76
+ if pattern =~ /t[eq]*h{3,}/
77
+ index = pattern =~ /t[eq]*h{3,}/
78
+ pattern = pattern[0..index]
79
+ lines = lines[0..index]
80
+ end
81
+
82
+ # if there still are some email headers, just remove them
83
+ while pattern =~ /h/
84
+ index = pattern =~ /h/
85
+ pattern.slice!(index)
86
+ lines.slice!(index)
87
+ end
88
+
89
+ # remove trailing quotes when there's at least one line of text
90
+ if pattern =~ /t/ && pattern =~ /[eq]+$/
91
+ index = pattern =~ /[eq]+$/
92
+ pattern = pattern[0...index]
93
+ lines = lines[0...index]
94
+ end
95
+
96
+ # result
97
+ lines.join("\n").strip
98
+ end
99
+
100
+ end
@@ -0,0 +1,14 @@
1
+ This is not a ---------- delimiter.
2
+
3
+ But there should be no delimiter after this line
4
+
5
+
6
+ --
7
+ ***
8
+ ####
9
+ ~~~~~
10
+ ======
11
+ _______
12
+ ++++++++
13
+
14
+ -------
@@ -0,0 +1,17 @@
1
+ This is a reply from Outlook!
2
+
3
+
4
+ ------------------------------
5
+
6
+ *From:* Outlook user
7
+ *Sent:* 2016-01-27
8
+ *To:* info@discourse.org
9
+ *Subject:* Are you using Outlook?
10
+
11
+
12
+
13
+ Just some random text wich is part
14
+
15
+ of the embedded email...
16
+
17
+ Outlook user
@@ -0,0 +1,10 @@
1
+ This is a reply from Outlook!
2
+ ________________________________________
3
+ From: Discourse <info@discourse.org.
4
+ Sent: Thursday, 28 January 2016 8:16 p.m.
5
+ To: Someone
6
+ Subject: (no subject)
7
+
8
+ Lorem ipsum.
9
+
10
+ Ipsor dolor sum met.
@@ -0,0 +1,8 @@
1
+ This is before the embedded email.
2
+
3
+ On Wed, Sep 25, 2013, at 03:57 PM, richard_clark wrote:
4
+
5
+ > This is the embedded email
6
+
7
+ This is after the embedded email and will not show up because 99% of the times
8
+ this is the signature...
@@ -0,0 +1,16 @@
1
+ I have checked the available documentation/links to find out the end points. If there are some other endpoints, can you please tell the endpoints
2
+
3
+ Best Regards
4
+
5
+
6
+
7
+
8
+ ---- On Tue, 22 Dec 2015 14:17:36 +0530 Sam Saffron&lt;info@discourse.org&gt; wrote ----
9
+
10
+
11
+ sam Sam Saffron co-founder
12
+ December 22
13
+ You are not using the right endpoint, go to user profile / badges, have a look at dev tools to see what it calls
14
+ There is a discrete endpoint to get all the badges a user has
15
+
16
+ To respond, reply to this email or visit the topic.
@@ -0,0 +1,24 @@
1
+ Sure, [Bitnami](http://bitnami.com/stack/discourse) supports EC2 and there
2
+ are several topics here about it.
3
+
4
+ Our [official install guide](
5
+ https://github.com/discourse/discourse/blob/master/docs/INSTALL-ubuntu.md)
6
+ also works great on an Amazon EC2 provisioned virtual machine with very
7
+ little change.
8
+
9
+
10
+ On Thu, Jun 20, 2013 at 4:18 PM, matt2 via Discourse Meta <
11
+ info@discourse.org> wrote:
12
+
13
+ > matt2 posted in 'Discourse on Ubuntu: Video Walkthrough' on Discourse Meta:
14
+ > ------------------------------
15
+ >
16
+ > Has anyone tried on AWS? a public AMI would be awesome.
17
+ > ------------------------------
18
+ >
19
+ > Please visit this link to respond:
20
+ > http://meta.discourse.org/t/discourse-on-ubuntu-video-walkthrough/7478/4
21
+ >
22
+ > To unsubscribe from these emails, visit your user preferences<http://meta.discourse.org/user_preferences>
23
+ > .
24
+ >
@@ -0,0 +1,19 @@
1
+ If I do exactly that, then the test group won't be saved after a refresh of
2
+ the page.
3
+
4
+
5
+ 2013/7/20 sam via Discourse Meta <info@discourse.org>
6
+
7
+ > sam replied to your post in 'Unable to create group' on Discourse Meta:
8
+ > ------------------------------
9
+ >
10
+ > Is this an error handling thing, if you name the group "test" and only
11
+ > place yourself in it, does it persist?
12
+ > ------------------------------
13
+ >
14
+ > To respond, reply to this email or visit
15
+ > http://meta.discourse.org/t/unable-to-create-group/8198/6 in your browser.
16
+ >
17
+ > To unsubscribe from these emails, visit your user preferences<http://meta.discourse.org/user_preferences>
18
+ > .
19
+ >
@@ -0,0 +1,5 @@
1
+ I am testing the SOMEONE_EMAIL_WROTE_REGEX regular expression.
2
+
3
+ Some One <info@discourse.org> wrote:
4
+
5
+ Something that will be considered as the embedded email.
@@ -0,0 +1,11 @@
1
+ Ensuring that ON_DATE_SOMEONE_WROTE_REGEXES is not greedy.
2
+
3
+ On this day
4
+
5
+ I wrote something
6
+
7
+ which was very interesting.
8
+
9
+ On 28 Jan 2016, at 19:04, Some One wrote:
10
+
11
+ > Did you write something interesting?
@@ -0,0 +1,20 @@
1
+ This is a line before the embedded email.
2
+ On Tue, 2011-03-01 at 18:02 +0530, Some One wrote:
3
+ > Hello
4
+ >
5
+ > This is the embedded email.
6
+
7
+ This is some text
8
+
9
+ after the
10
+
11
+ embedded email.
12
+
13
+ >
14
+ > This is another part of the embedded email.
15
+ >
16
+ >
17
+
18
+
19
+ _______________________
20
+ And here's my signature.
@@ -0,0 +1,5 @@
1
+ Foo
2
+
3
+ -------- Original Message --------
4
+
5
+ THE END.
@@ -0,0 +1,13 @@
1
+ Nice of you to pick it up! Could you make a PR? Then other people can use it too. Would be great.
2
+
3
+
4
+ > Op 2 feb. 2015 om 05:28 heeft VannillaSky <info@discourse.org> het volgende geschreven:
5
+ >
6
+ >
7
+ > VannillaSky
8
+ > February 2
9
+ > Solved. Going forward...
10
+ >
11
+ > To respond, reply to this email or visit https://meta.discourse.org/t/import-posts-from-facebook-group-into-discourse/6089/33 in your browser.
12
+ >
13
+ > To unsubscribe from these emails, visit your user preferences.
@@ -0,0 +1,62 @@
1
+ The adblocker idea from @elberet might be it. Regretfully I only have time
2
+ to test this in 2 weeks. I will let you know then...
3
+ Op 16 aug. 2014 05:13 schreef "codinghorror" <info@discourse.org> het
4
+ volgende geschreven:
5
+
6
+ > codinghorror <https://meta.discourse.org/users/codinghorror>
7
+ > August 15
8
+ >
9
+ > Hmm, if that is true we need to fix that somehow.
10
+ >
11
+ > To respond, reply to this email or visit
12
+ > https://meta.discourse.org/t/configuring-google-oauth2-login-for-discourse/15858/38
13
+ > in your browser.
14
+ > ------------------------------
15
+ > Previous Replies elberet <https://meta.discourse.org/users/elberet>
16
+ > August 15
17
+ >
18
+ > Are you using an ad blocker? Adblock Plus, for instance, removes the login
19
+ > buttons.
20
+ > bwvanmanen <https://meta.discourse.org/users/bwvanmanen>
21
+ > August 15
22
+ >
23
+ > The 'Sign in with Google' button does appear when I try to log in from
24
+ > another pc. However the button does not appear on my pc using another
25
+ > browser.
26
+ > bwvanmanen <https://meta.discourse.org/users/bwvanmanen>
27
+ > August 15
28
+ >
29
+ > I followed the steps from the opening post, but I don't get a google login
30
+ > option when users try to log in. There is just the normal user/password,
31
+ > the word OR, and nothing next to that. Any clues?
32
+ >
33
+ > neil <https://meta.discourse.org/users/neil>
34
+ > August 1
35
+ >
36
+ > Glad you got it fixed. It's good to have the resolution in this topic too.
37
+ > I added a link to your topic in the first post.
38
+ > jgehrcke <https://meta.discourse.org/users/jgehrcke>
39
+ > July 31
40
+ >
41
+ > Sorry, that was kind of a cross-posting. Indeed, I got that fixed as you
42
+ > say, as reported here:
43
+ > jgehrcke said:
44
+ >
45
+ > I understand the solution you are proposing. The proper fix, without
46
+ > customizing the disource.conf in the container, however, would be to inform
47
+ > the web application about the protocol used via an HTTP header, as you are
48
+ > also suggesting. The question is: does Discourse respect/support
49
+ > X-Forwarded-Protocol? Then I can easily configure the nginx reverse proxy
50
+ > with proxy_set_header X-Forwarded-Protocol $scheme; Edit: I can confirm
51
+ > that properly setting the X-Forwarded-Proto header in the nginx …
52
+ >
53
+ > Thanks and sorry for not reporting back here!
54
+ > ------------------------------
55
+ >
56
+ > To respond, reply to this email or visit
57
+ > https://meta.discourse.org/t/configuring-google-oauth2-login-for-discourse/15858/38
58
+ > in your browser.
59
+ >
60
+ > To unsubscribe from these emails, visit your user preferences
61
+ > <https://meta.discourse.org/my/preferences>.
62
+ >
@@ -0,0 +1,12 @@
1
+ C'est super !
2
+ Le 4 janv. 2016 19:03, "Neil Lalonde"
3
+ <info@discourse.org>
4
+ a écrit :
5
+
6
+ > <https://meta.discourse.org/users/neil> team
7
+ > January 4
8
+ >
9
+ > Discourse c'est top !
10
+ >
11
+ > Neil
12
+ >
@@ -0,0 +1,26 @@
1
+ alright, no big deal - I assume in this case the code needs some refactoring to better support I18N anyway.
2
+
3
+
4
+
5
+ codinghorror via Discourse Meta <info@discourse.org> schrieb:
6
+ >codinghorror posted in 'Visually separate "Like it too" / "Undo like"'
7
+ >on Discourse Meta:
8
+ >
9
+ >---
10
+ >So turns out this is sort of a complex change for something so small.
11
+ >Our code at that location assumes all phrases end in periods. Changing
12
+ >that conditionally to sometimes an em-dash, sometimes not, is kind of..
13
+ >a pain in the butt.
14
+ >
15
+ >Will keep an eye on it, but low priority given the work required.
16
+ >
17
+ >---
18
+ >To respond, reply to this email or visit
19
+ >http://meta.discourse.org/t/visually-separate-like-it-too-undo-like/8464/3
20
+ >in your browser.
21
+ >
22
+ >To unsubscribe from these emails, visit your [user
23
+ >preferences](http://meta.discourse.org/user_preferences).
24
+
25
+ --
26
+ Diese Nachricht wurde von meinem Android-Mobiltelefon mit K-9 Mail gesendet.
@@ -0,0 +1,34 @@
1
+ Oh, I've forgot to add. MIT
2
+
3
+ --
4
+ Łukasz Jan Niemier
5
+
6
+ Dnia 14 lip 2015 o godz. 00:25 Michael Downey <info@discourse.org> napisał(a):
7
+
8
+ >
9
+ > downey Michael Downey Senior Tester
10
+ > July 13
11
+ > Sounds interesting. What is the license?
12
+ >
13
+ > To respond, reply to this email or visit https://meta.discourse.org/t/static-pages-plugin/31027/2 in your browser.
14
+ >
15
+ > Previous Replies
16
+ >
17
+ > hauleth
18
+ > July 13
19
+ > WIP
20
+ >
21
+ > Location: https://github.com/hauleth/low_voltage
22
+ >
23
+ > Authors: @hauleth
24
+ >
25
+ > Simple plugin to add "static" pages to Discourse instance. For now usage is kind of complicated at it needs to fetch static pages from app/views/pages. Ideas for future implements:
26
+ >
27
+ > Create DB model to hold pages
28
+ > Adding admin page that will allow editing that pages
29
+ > Custom styles for static pages
30
+ > Any help appreciated.
31
+ >
32
+ > To respond, reply to this email or visit https://meta.discourse.org/t/static-pages-plugin/31027/2 in your browser.
33
+ >
34
+ > To unsubscribe from these emails, visit your user preferences.
@@ -0,0 +1,18 @@
1
+ Olá,
2
+ Qualquer dúvida estamos ai.
3
+
4
+ Em 2 de fevereiro de 2015 10:58, discourse <
5
+ info@discourse.org> escreveu:
6
+
7
+ > discourse <https://meta.discourse.org/users/discourse>
8
+ > February 2
9
+ >
10
+ > Bom dia. Obrigado pela atenção
11
+ > ------------------------------
12
+ >
13
+ > To respond, reply to this email or visit
14
+ > https://meta.discourse.org/ in your browser.
15
+ >
16
+ > To unsubscribe from these emails, visit your user preferences
17
+ > <https://meta.discourse.org/my/preferences>.
18
+ >
@@ -0,0 +1,10 @@
1
+ On Mon, Aug 19, 2013 at 2:36 AM, SomeOne via Discourse Meta <
2
+ info@discourse.org> wrote:
3
+
4
+ > This seems like a problem that would be better solved at the web server
5
+ > level, rather than by the application. If nothing else, adding an instance
6
+ > of Nginx as an SSL/TLS reverse-proxy would very quickly take care of this.
7
+ >
8
+
9
+ when I said looks possible, I pointed to rack because that's still the web
10
+ server level
@@ -0,0 +1,27 @@
1
+ Why don't you override particular strings with JS?
2
+
3
+ понедельник, 6 октября 2014 г. пользователь lidel написал:
4
+
5
+ > lidel <https://meta.discourse.org/users/lidel>
6
+ > October 6
7
+ > winterbox:
8
+ >
9
+ > Do you have any plan to make this plugin?
10
+ >
11
+ > discourse-locale-override
12
+ > <https://github.com/lidel/discourse-locale-override> is just a hack, and
13
+ > as @sam <https://meta.discourse.org/users/sam> pointed out, it only works
14
+ > if you update your instance via commandline. I created it to speed up my
15
+ > work on pl_PL translation only.
16
+ >
17
+ > I see there is a need for a proper plugin (this and other threads), but
18
+ > until such plugin appears this is a semi-working workaround.
19
+ > ------------------------------
20
+ >
21
+ > To respond, reply to this email or visit
22
+ > https://meta.discourse.org/t/use-custom-translation-file/13786/41 in your
23
+ > browser.
24
+ >
25
+ > To unsubscribe from these emails, visit your user preferences
26
+ > <https://meta.discourse.org/my/preferences>.
27
+ >
@@ -0,0 +1,41 @@
1
+ I've configured Twitter Authentication, so this error happends on the
2
+ application, after twitter posts to my discourse install via the callback.
3
+
4
+ In the front error I can get a correct message saying "Something waa wrong,
5
+ check you usename and password" and in the backend I see that error in the
6
+ logs.
7
+
8
+
9
+
10
+ El jueves, 21 de noviembre de 2013, codinghorror escribió:
11
+
12
+ > codinghorror <http://meta.discourse.org/users/codinghorror>
13
+ > November 21
14
+ >
15
+ > How are you creating this user? Describe it step by step.
16
+ >
17
+ > To respond, reply to this email or visit
18
+ > http://meta.discourse.org/t/error-creating-new-users-pg-numericvalueoutofrange/11046/2in your browser.
19
+ > ------------------------------
20
+ > Previous Replies PabloC <http://meta.discourse.org/users/pabloc>
21
+ > November 21
22
+ >
23
+ > Hi guys,
24
+ >
25
+ > While I create a new user, I'm finding this error in the logs :
26
+ >
27
+ > Processing by UsersController#create as */*
28
+ > Parameters: {"name"=>"Ps4 Support Forum", "email"=>"pablocorral+ps4@gmail.com <javascript:_e({}, 'cvml', 'pablocorral%2Bps4@gmail.com');>", "username"=>"PS4SupportForum", "password_confirmation"=>"[FILTERED]", "challenge"=>"11a4ebe83d9b2a9e0d45bc50b457ee17"}
29
+ > PG::NumericValueOutOfRange: ERROR: value "2201945804" is out of range for type integer
30
+ >
31
+ > Any idea?
32
+ >
33
+ > Tks!
34
+ > ------------------------------
35
+ >
36
+ > To respond, reply to this email or visit
37
+ > http://meta.discourse.org/t/error-creating-new-users-pg-numericvalueoutofrange/11046/2in your browser.
38
+ >
39
+ > To unsubscribe from these emails, visit your user preferences<http://meta.discourse.org/user_preferences>
40
+ > .
41
+ >
@@ -0,0 +1,9 @@
1
+ ---------- Forwarded message ----------
2
+ From: Some One <foo@bar.com>
3
+ Date: Thu, Jan 28, 2016 at 4:00 PM
4
+ Subject: Some subject that
5
+ spans over 2 lines
6
+ To: infod@discourse.org
7
+
8
+
9
+ This is a forwarded email. And just that.
@@ -0,0 +1,4 @@
1
+ Email with
2
+ windows
3
+ line
4
+ endings
@@ -0,0 +1,3 @@
1
+ > This is a quote.
2
+
3
+ And this is some text.
@@ -0,0 +1 @@
1
+ > Email with only quote.
@@ -0,0 +1,14 @@
1
+ Formatting and
2
+
3
+ spaces
4
+
5
+ - A
6
+ - B
7
+ - C
8
+
9
+ should be retained
10
+
11
+
12
+ - Item #1
13
+ - Item #2
14
+
@@ -0,0 +1,27 @@
1
+ This email was sent from way too much different devices ;)
2
+
3
+ Envoyé depuis mon iPhone
4
+
5
+ Von meinem Mobilgerät gesendet
6
+ Diese Nachricht wurde von meinem Android-Mobiltelefon mit K-9 Mail gesendet.
7
+
8
+ Someone from mobile
9
+ From My Iphone 6
10
+ Sent via mobile
11
+ Sent with Airmail
12
+ Sent from Windows Mail
13
+ Sent from Mailbox
14
+ Sent from Mailbox for iPad
15
+ Sent from Yahoo Mail on Android
16
+ Sent from my TI-85
17
+ Sent from my iPhone
18
+ Sent from my iPod
19
+ Sent from my Alcatel Flash2
20
+ Sent from my mobile device
21
+ Sent from my cell, please excuse any typos.
22
+ Sent from my Samsung Galaxy s5 Octacore device
23
+ Sent from my HTC M8 Android phone. Please excuse typoze
24
+ Sent from my Windows 8 PC <http://windows.microsoft.com/consumer-preview>
25
+ <<sent by galaxy>>
26
+ (sent from a phone)
27
+ (Sent from mobile device)
@@ -0,0 +1,10 @@
1
+
2
+
3
+
4
+
5
+
6
+ Strip leading and trailing empty lines.
7
+
8
+
9
+
10
+
@@ -0,0 +1 @@
1
+ Email with only text.
@@ -0,0 +1,3 @@
1
+ This is not a ---------- delimiter.
2
+
3
+ But there should be no delimiter after this line
@@ -0,0 +1 @@
1
+ This is a reply from Outlook!
@@ -0,0 +1 @@
1
+ This is a reply from Outlook!
@@ -0,0 +1 @@
1
+ This is before the embedded email.
@@ -0,0 +1,3 @@
1
+ I have checked the available documentation/links to find out the end points. If there are some other endpoints, can you please tell the endpoints
2
+
3
+ Best Regards
@@ -0,0 +1,7 @@
1
+ Sure, [Bitnami](http://bitnami.com/stack/discourse) supports EC2 and there
2
+ are several topics here about it.
3
+
4
+ Our [official install guide](
5
+ https://github.com/discourse/discourse/blob/master/docs/INSTALL-ubuntu.md)
6
+ also works great on an Amazon EC2 provisioned virtual machine with very
7
+ little change.
@@ -0,0 +1,2 @@
1
+ If I do exactly that, then the test group won't be saved after a refresh of
2
+ the page.
@@ -0,0 +1 @@
1
+ I am testing the SOMEONE_EMAIL_WROTE_REGEX regular expression.
@@ -0,0 +1,7 @@
1
+ Ensuring that ON_DATE_SOMEONE_WROTE_REGEXES is not greedy.
2
+
3
+ On this day
4
+
5
+ I wrote something
6
+
7
+ which was very interesting.
@@ -0,0 +1,19 @@
1
+ This is a line before the embedded email.
2
+
3
+ > Hello
4
+ >
5
+ > This is the embedded email.
6
+
7
+ This is some text
8
+
9
+ after the
10
+
11
+ embedded email.
12
+
13
+ >
14
+ > This is another part of the embedded email.
15
+ >
16
+ >
17
+
18
+
19
+ And here's my signature.
@@ -0,0 +1 @@
1
+ Foo
@@ -0,0 +1 @@
1
+ Nice of you to pick it up! Could you make a PR? Then other people can use it too. Would be great.
@@ -0,0 +1,2 @@
1
+ The adblocker idea from @elberet might be it. Regretfully I only have time
2
+ to test this in 2 weeks. I will let you know then...
@@ -0,0 +1 @@
1
+ C'est super !
@@ -0,0 +1 @@
1
+ alright, no big deal - I assume in this case the code needs some refactoring to better support I18N anyway.
@@ -0,0 +1,3 @@
1
+ Oh, I've forgot to add. MIT
2
+
3
+ Łukasz Jan Niemier
@@ -0,0 +1,2 @@
1
+ Olá,
2
+ Qualquer dúvida estamos ai.
@@ -0,0 +1,7 @@
1
+ > This seems like a problem that would be better solved at the web server
2
+ > level, rather than by the application. If nothing else, adding an instance
3
+ > of Nginx as an SSL/TLS reverse-proxy would very quickly take care of this.
4
+ >
5
+
6
+ when I said looks possible, I pointed to rack because that's still the web
7
+ server level
@@ -0,0 +1 @@
1
+ Why don't you override particular strings with JS?
@@ -0,0 +1,6 @@
1
+ I've configured Twitter Authentication, so this error happends on the
2
+ application, after twitter posts to my discourse install via the callback.
3
+
4
+ In the front error I can get a correct message saying "Something waa wrong,
5
+ check you usename and password" and in the backend I see that error in the
6
+ logs.
@@ -0,0 +1 @@
1
+ This is a forwarded email. And just that.
@@ -0,0 +1,4 @@
1
+ Email with
2
+ windows
3
+ line
4
+ endings
@@ -0,0 +1,3 @@
1
+ > This is a quote.
2
+
3
+ And this is some text.
@@ -0,0 +1 @@
1
+ > Email with only quote.
@@ -0,0 +1,14 @@
1
+ Formatting and
2
+
3
+ spaces
4
+
5
+ - A
6
+ - B
7
+ - C
8
+
9
+ should be retained
10
+
11
+
12
+ - Item #1
13
+ - Item #2
14
+
@@ -0,0 +1 @@
1
+ This email was sent from way too much different devices ;)
@@ -0,0 +1 @@
1
+ Strip leading and trailing empty lines.
@@ -0,0 +1 @@
1
+ Email with only text.
@@ -0,0 +1,33 @@
1
+ require "minitest/autorun"
2
+ require "email_reply_trimmer"
3
+
4
+ class TestEmailReplyTrimmer < Minitest::Test
5
+
6
+ EMAILS = Dir["test/emails/*.txt"].map { |path| File.basename(path) }
7
+ REPLIES = Dir["test/replies/*.txt"].map { |path| File.basename(path) }
8
+
9
+ def test_all_emails_have_a_matching_reply
10
+ assert_equal EMAILS, REPLIES, "Files in /emails and /replies folders should match 1-to-1"
11
+ end
12
+
13
+ def test_normalize_line_endings_email_has_windows_line_endings
14
+ assert_match /\r\n/, File.read("test/emails/normalize_line_endings.txt")
15
+ end
16
+
17
+ EMAILS.each do |filename|
18
+ name = File.basename(filename, ".txt")
19
+ define_method("test_#{name}") do
20
+ assert_equal trim(filename), reply(filename), "EMAIL: #{filename}"
21
+ end
22
+ end
23
+
24
+ def trim(filename)
25
+ body = File.read("test/emails/#{filename}")
26
+ EmailReplyTrimmer.trim(body)
27
+ end
28
+
29
+ def reply(filename)
30
+ File.read("test/replies/#{filename}").strip
31
+ end
32
+
33
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: email_reply_trimmer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Régis Hanol
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: EmailReplyTrimmer is a small library to trim replies from plain text
14
+ email.
15
+ email:
16
+ - regis+rubygems@hanol.fr
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - LICENSE
22
+ - README.md
23
+ - Rakefile
24
+ - email_reply_trimmer.gemspec
25
+ - lib/email_reply_trimmer.rb
26
+ - lib/email_reply_trimmer/delimiter_matcher.rb
27
+ - lib/email_reply_trimmer/email_header_matcher.rb
28
+ - lib/email_reply_trimmer/embedded_email_matcher.rb
29
+ - lib/email_reply_trimmer/empty_line_matcher.rb
30
+ - lib/email_reply_trimmer/quote_matcher.rb
31
+ - lib/email_reply_trimmer/signature_matcher.rb
32
+ - test/emails/delimiters.txt
33
+ - test/emails/email_headers_1.txt
34
+ - test/emails/email_headers_2.txt
35
+ - test/emails/embedded_email_1.txt
36
+ - test/emails/embedded_email_2.txt
37
+ - test/emails/embedded_email_3.txt
38
+ - test/emails/embedded_email_4.txt
39
+ - test/emails/embedded_email_5.txt
40
+ - test/emails/embedded_email_6.txt
41
+ - test/emails/embedded_email_7.txt
42
+ - test/emails/embedded_email_8.txt
43
+ - test/emails/embedded_email_dutch_1.txt
44
+ - test/emails/embedded_email_dutch_2.txt
45
+ - test/emails/embedded_email_french.txt
46
+ - test/emails/embedded_email_german.txt
47
+ - test/emails/embedded_email_polish.txt
48
+ - test/emails/embedded_email_portuguese.txt
49
+ - test/emails/embedded_email_quote_text.txt
50
+ - test/emails/embedded_email_russian.txt
51
+ - test/emails/embedded_email_spanish.txt
52
+ - test/emails/forwarded_message.txt
53
+ - test/emails/normalize_line_endings.txt
54
+ - test/emails/quote_and_text.txt
55
+ - test/emails/quote_only.txt
56
+ - test/emails/retains_spaces_and_formatting.txt
57
+ - test/emails/signatures.txt
58
+ - test/emails/strip.txt
59
+ - test/emails/text_only.txt
60
+ - test/replies/delimiters.txt
61
+ - test/replies/email_headers_1.txt
62
+ - test/replies/email_headers_2.txt
63
+ - test/replies/embedded_email_1.txt
64
+ - test/replies/embedded_email_2.txt
65
+ - test/replies/embedded_email_3.txt
66
+ - test/replies/embedded_email_4.txt
67
+ - test/replies/embedded_email_5.txt
68
+ - test/replies/embedded_email_6.txt
69
+ - test/replies/embedded_email_7.txt
70
+ - test/replies/embedded_email_8.txt
71
+ - test/replies/embedded_email_dutch_1.txt
72
+ - test/replies/embedded_email_dutch_2.txt
73
+ - test/replies/embedded_email_french.txt
74
+ - test/replies/embedded_email_german.txt
75
+ - test/replies/embedded_email_polish.txt
76
+ - test/replies/embedded_email_portuguese.txt
77
+ - test/replies/embedded_email_quote_text.txt
78
+ - test/replies/embedded_email_russian.txt
79
+ - test/replies/embedded_email_spanish.txt
80
+ - test/replies/forwarded_message.txt
81
+ - test/replies/normalize_line_endings.txt
82
+ - test/replies/quote_and_text.txt
83
+ - test/replies/quote_only.txt
84
+ - test/replies/retains_spaces_and_formatting.txt
85
+ - test/replies/signatures.txt
86
+ - test/replies/strip.txt
87
+ - test/replies/text_only.txt
88
+ - test/test_email_reply_trimmer.rb
89
+ homepage: https://github.com/discourse/email_reply_trimmer
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.4.5
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Library to trim replies from plain text email.
113
+ test_files: []
114
+ has_rdoc: