mailcatcher 0.5.12 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 087ab236a57889861232c36337622a2c491f015e
4
- data.tar.gz: 2025e9693e21dae93e87d28261ae520ea3b1d4f8
2
+ SHA256:
3
+ metadata.gz: 398459f93087b0066f8e2f8fd34781c2db1c6c3a8b2e13183a5cc425765f3347
4
+ data.tar.gz: 167623ed70957092aa6609d872cec9098f4d92184033df8b1cda9f83a2d8a31d
5
5
  SHA512:
6
- metadata.gz: 96f670bb993dc0f567da90089a88effdec7ec1f4fcd30d85e7f0d63a9ee18446f4edd0b6ebbb48a3062d0f7bd0cfb9fe41cfd0edea05d53864cfc5930b034121
7
- data.tar.gz: 42daf4cd55e174e109c08c041261ac3cd5597b57fdcb5a6e632a31e838f8a4b7f828a24871e18833aa5de6635848065d150ee93f7eaab3f9aef0df0ed6f19b31
6
+ metadata.gz: 65dcc3d2041456601dfd69f4cb522817522b7243cc1ac09b2e08c3905693cf99063aad8f262154577d2ad3ea94836c27cd0be7f1186cadf2abab7f968b7778e4
7
+ data.tar.gz: 71bbe2396c4ba43857d346a5ee93269e314ac2cf4f694babfaf7a79c96f4d6c9f86d1df76f66b76e4e8df272371963c94418f07ce5cc2a9d204a13a0f4b3ea7b
checksums.yaml.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -4,65 +4,119 @@ Catches mail and serves it through a dream.
4
4
 
5
5
  MailCatcher runs a super simple SMTP server which catches any message sent to it to display in a web interface. Run mailcatcher, set your favourite app to deliver to smtp://127.0.0.1:1025 instead of your default SMTP server, then check out http://127.0.0.1:1080 to see the mail that's arrived so far.
6
6
 
7
- ![MailCatcher screenshot](http://f.cl.ly/items/3w2T1p0F3g003b2i1F2z/Screen%20shot%202011-06-23%20at%2011.39.03%20PM.png)
7
+ ![MailCatcher screenshot](https://cloud.githubusercontent.com/assets/14028/14093249/4100f904-f598-11e5-936b-e6a396f18e39.png)
8
8
 
9
9
  ## Features
10
10
 
11
11
  * Catches all mail and stores it for display.
12
12
  * Shows HTML, Plain Text and Source version of messages, as applicable.
13
- * Rewrites HTML enabling display of embedded, inline images/etc and open links in a new window. (currently very basic)
14
- * Can send HTML for analysis by [Fractal][fractal].
13
+ * Rewrites HTML enabling display of embedded, inline images/etc and opens links in a new window.
15
14
  * Lists attachments and allows separate downloading of parts.
16
15
  * Download original email to view in your native mail client(s).
17
16
  * Command line options to override the default SMTP/HTTP IP and port settings.
18
17
  * Mail appears instantly if your browser supports [WebSockets][websockets], otherwise updates every thirty seconds.
19
- * Growl notifications when you receive a new message.
20
- * Runs as a daemon run in the background.
21
- * Sendmail-analogue command, `catchmail`, makes [using mailcatcher from PHP][withphp] a lot easier.
22
- * Written super-simply in EventMachine, easy to dig in and change.
18
+ * Runs as a daemon in the background, optionally in foreground.
19
+ * Sendmail-analogue command, `catchmail`, makes using mailcatcher from PHP a lot easier.
23
20
  * Keyboard navigation between messages
24
21
 
25
22
  ## How
26
23
 
27
24
  1. `gem install mailcatcher`
28
25
  2. `mailcatcher`
29
- 3. Go to http://localhost:1080/
30
- 4. Send mail through smtp://localhost:1025
26
+ 3. Go to http://127.0.0.1:1080/
27
+ 4. Send mail through smtp://127.0.0.1:1025
31
28
 
32
- The brave can get the source from [the GitHub repository][mailcatcher-github].
29
+ ### Command Line Options
30
+
31
+ Use `mailcatcher --help` to see the command line options.
32
+
33
+ ```
34
+ Usage: mailcatcher [options]
35
+
36
+ MailCatcher v0.8.0
37
+
38
+ --ip IP Set the ip address of both servers
39
+ --smtp-ip IP Set the ip address of the smtp server
40
+ --smtp-port PORT Set the port of the smtp server
41
+ --http-ip IP Set the ip address of the http server
42
+ --http-port PORT Set the port address of the http server
43
+ --messages-limit COUNT Only keep up to COUNT most recent messages
44
+ --http-path PATH Add a prefix to all HTTP paths
45
+ --no-quit Don't allow quitting the process
46
+ -f, --foreground Run in the foreground
47
+ -b, --browse Open web browser
48
+ -v, --verbose Be more verbose
49
+ -h, --help Display this help information
50
+ --version Display the current version
51
+ ```
52
+
53
+ ### Ruby
54
+
55
+ If you have trouble with the setup commands, make sure you have [Ruby installed](https://www.ruby-lang.org/en/documentation/installation/):
56
+
57
+ ```
58
+ ruby -v
59
+ gem environment
60
+ ```
61
+
62
+ You might need to install build tools for some of the gem dependencies. On Debian or Ubuntu, `apt install build-essential`. On macOS, `xcode-select --install`.
63
+
64
+ If you encounter issues installing [thin](https://rubygems.org/gems/thin), try:
65
+
66
+ ```
67
+ gem install thin -v 1.5.1 -- --with-cflags="-Wno-error=implicit-function-declaration"
68
+ ```
33
69
 
34
70
  ### Bundler
35
71
 
36
- Please don't put mailcatcher into your Gemfile. It will conflict with your applications gems at some point.
72
+ Please don't put mailcatcher into your Gemfile. It will conflict with your application's gems at some point.
37
73
 
38
- Instead, pop a note in your README stating you use mailcatcher. Simply run `gem install mailcatcher` then `mailcatcher` to get started.
74
+ Instead, pop a note in your README stating you use mailcatcher, and to run `gem install mailcatcher` then `mailcatcher` to get started.
39
75
 
40
76
  ### RVM
41
77
 
42
- Under RVM your mailcatcher command may only be available under the ruby you install mailcatcher into. To prevent this, and to prevent gem conflicts, install mailcatcher into a dedicated gemset and create wrapper scripts:
78
+ Under RVM your mailcatcher command may only be available under the ruby you install mailcatcher into. To prevent this, and to prevent gem conflicts, install mailcatcher into a dedicated gemset with a wrapper script:
43
79
 
44
80
  rvm default@mailcatcher --create do gem install mailcatcher
45
- rvm wrapper default@mailcatcher --no-prefix mailcatcher catchmail
81
+ ln -s "$(rvm default@mailcatcher do rvm wrapper show mailcatcher)" "$rvm_bin_path/"
46
82
 
47
83
  ### Rails
48
84
 
49
- To set up your rails app, I recommend adding this to your `environment/development.rb`:
85
+ To set up your rails app, I recommend adding this to your `environments/development.rb`:
50
86
 
51
87
  config.action_mailer.delivery_method = :smtp
52
- config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 }
88
+ config.action_mailer.smtp_settings = { :address => '127.0.0.1', :port => 1025 }
89
+ config.action_mailer.raise_delivery_errors = false
53
90
 
54
91
  ### PHP
55
92
 
56
- For projects using PHP, or PHP frameworks and application platforms like Drupal, you can set [PHP's mail configuration](http://www.php.net/manual/en/mail.configuration.php) in your [php.ini](http://www.php.net/manual/en/configuration.file.php) to send via MailCatcher with:
93
+ For projects using PHP, or PHP frameworks and application platforms like Drupal, you can set [PHP's mail configuration](https://www.php.net/manual/en/mail.configuration.php) in your [php.ini](https://www.php.net/manual/en/configuration.file.php) to send via MailCatcher with:
57
94
 
58
- sendmail_path = /usr/bin/env catchmail
95
+ sendmail_path = /usr/bin/env catchmail -f some@from.address
59
96
 
60
- You can do this in an [Apache htaccess file](http://php.net/manual/en/configuration.changes.php) or general configuration like so:
97
+ You can do this in your [Apache configuration](https://www.php.net/manual/en/configuration.changes.php) like so:
61
98
 
62
- php_value sendmail_path "/usr/bin/env catchmail"
99
+ php_admin_value sendmail_path "/usr/bin/env catchmail -f some@from.address"
63
100
 
64
101
  If you've installed via RVM this probably won't work unless you've manually added your RVM bin paths to your system environment's PATH. In that case, run `which catchmail` and put that path into the `sendmail_path` directive above instead of `/usr/bin/env catchmail`.
65
102
 
103
+ If starting `mailcatcher` on alternative SMTP IP and/or port with parameters like `--smtp-ip 192.168.0.1 --smtp-port 10025`, add the same parameters to your `catchmail` command:
104
+
105
+ sendmail_path = /usr/bin/env catchmail --smtp-ip 192.160.0.1 --smtp-port 10025 -f some@from.address
106
+
107
+ ### Django
108
+
109
+ For use in Django, add the following configuration to your projects' settings.py
110
+
111
+ ```python
112
+ if DEBUG:
113
+ EMAIL_HOST = '127.0.0.1'
114
+ EMAIL_HOST_USER = ''
115
+ EMAIL_HOST_PASSWORD = ''
116
+ EMAIL_PORT = 1025
117
+ EMAIL_USE_TLS = False
118
+ ```
119
+
66
120
  ### API
67
121
 
68
122
  A fairly RESTful URL schema means you can download a list of messages in JSON from `/messages`, each message's metadata with `/messages/:id.json`, and then the pertinent parts with `/messages/:id.html` and `/messages/:id.plain` for the default HTML and plain text version, `/messages/:id/:cid` for individual attachments by CID, or the whole message with `/messages/:id.source`.
@@ -70,41 +124,22 @@ A fairly RESTful URL schema means you can download a list of messages in JSON fr
70
124
  ## Caveats
71
125
 
72
126
  * Mail processing is fairly basic but easily modified. If something doesn't work for you, fork and fix it or [file an issue][mailcatcher-issues] and let me know. Include the whole message you're having problems with.
73
- * The interface is very basic and has not been tested on many browsers yet.
74
-
75
- ## TODO
76
-
77
- * Add mail delivery on request, optionally multiple times.
78
- * Better Growl support in MacRuby and RubyCocoa with click notifications which takes you to the received message.
79
- * An API-compatible nodejs version, for fun and profit (and non-ruby npm users).
80
- * Test suite.
81
- * Compatibility testing against CampaignMonitor's [design guidelines](http://www.campaignmonitor.com/design-guidelines/) and [CSS support matrix](http://www.campaignmonitor.com/design-guidelines/).
82
- * Forward mail to rendering service, maybe CampaignMonitor?
83
- * Package as an app? Native interfaces? HotCocoa?
127
+ * Encodings are difficult. MailCatcher does not completely support utf-8 straight over the wire, you must use a mail library which encodes things properly based on SMTP server capabilities.
84
128
 
85
129
  ## Thanks
86
130
 
87
131
  MailCatcher is just a mishmash of other people's hard work. Thank you so much to the people who have built the wonderful guts on which this project relies.
88
132
 
89
- Thanks also to [The Frontier Group][tfg] for giving me the idea, being great guinea pigs and letting me steal pieces of time to keep the project alive.
90
-
91
133
  ## Donations
92
134
 
93
135
  I work on MailCatcher mostly in my own spare time. If you've found Mailcatcher useful and would like to help feed me and fund continued development and new features, please [donate via PayPal][donate]. If you'd like a specific feature added to MailCatcher and are willing to pay for it, please [email me](mailto:sj26@sj26.com).
94
136
 
95
137
  ## License
96
138
 
97
- Copyright © 2010-2011 Samuel Cochran (sj26@sj26.com). Released under the MIT License, see [LICENSE][license] for details.
98
-
99
- ## Dreams
100
-
101
- For dream catching, try [this](http://goo.gl/kgbh). OR [THIS](http://www.nyanicorn.com), OMG.
139
+ Copyright © 2010-2019 Samuel Cochran (sj26@sj26.com). Released under the MIT License, see [LICENSE][license] for details.
102
140
 
103
141
  [donate]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=522WUPLRWUSKE
104
- [fractal]: http://getfractal.com
105
142
  [license]: https://github.com/sj26/mailcatcher/blob/master/LICENSE
106
143
  [mailcatcher-github]: https://github.com/sj26/mailcatcher
107
144
  [mailcatcher-issues]: https://github.com/sj26/mailcatcher/issues
108
- [tfg]: http://www.thefrontiergroup.com.au
109
- [websockets]: http://www.whatwg.org/specs/web-socket-protocol/
110
- [withphp]: http://webschuur.com/publications/blogs/2011-05-29-catchmail_for_drupal_and_other_phpapplications_the_simple_version
145
+ [websockets]: https://tools.ietf.org/html/rfc6455
data/bin/catchmail CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  begin
4
5
  require 'mail'
@@ -13,7 +14,7 @@ options = {:smtp_ip => '127.0.0.1', :smtp_port => 1025}
13
14
 
14
15
  OptionParser.new do |parser|
15
16
  parser.banner = <<-BANNER.gsub /^ +/, ""
16
- Usage: catchmail [options]
17
+ Usage: catchmail [options] [recipient ...]
17
18
  sendmail-like interface to forward mail to MailCatcher.
18
19
  BANNER
19
20
 
@@ -33,6 +34,17 @@ OptionParser.new do |parser|
33
34
  options[:from] = from
34
35
  end
35
36
 
37
+ parser.on('-oi', 'Ignored option -oi') do |ignored|
38
+ end
39
+ parser.on('-t', 'Ignored option -t') do |ignored|
40
+ end
41
+ parser.on('-q', 'Ignored option -q') do |ignored|
42
+ end
43
+
44
+ parser.on('-x', '--no-exit', 'Can\'t exit from the application') do
45
+ options[:no_exit] = true
46
+ end
47
+
36
48
  parser.on('-h', '--help', 'Display this help information') do
37
49
  puts parser
38
50
  exit!
@@ -45,6 +57,16 @@ Mail.defaults do
45
57
  :port => options[:smtp_port]
46
58
  end
47
59
 
48
- message = Mail.new ARGF.read
60
+ message = Mail.new($stdin.read)
61
+
49
62
  message.return_path = options[:from] if options[:from]
63
+
64
+ ARGV.each do |recipient|
65
+ if message.to.nil?
66
+ message.to = recipient
67
+ else
68
+ message.to << recipient
69
+ end
70
+ end
71
+
50
72
  message.deliver
data/bin/mailcatcher CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'mail_catcher'
5
+
4
6
  MailCatcher.run!
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "eventmachine"
4
+
5
+ module MailCatcher
6
+ Bus = EventMachine::Channel.new
7
+ end
@@ -1,12 +1,14 @@
1
- require 'active_support/json'
2
- require 'mail'
3
- require 'sqlite3'
4
- require 'eventmachine'
1
+ # frozen_string_literal: true
2
+
3
+ require "eventmachine"
4
+ require "json"
5
+ require "mail"
6
+ require "sqlite3"
5
7
 
6
8
  module MailCatcher::Mail extend self
7
9
  def db
8
10
  @__db ||= begin
9
- SQLite3::Database.new(':memory:', :type_translation => true).tap do |db|
11
+ SQLite3::Database.new(":memory:", :type_translation => true).tap do |db|
10
12
  db.execute(<<-SQL)
11
13
  CREATE TABLE message (
12
14
  id INTEGER PRIMARY KEY ASC,
@@ -30,9 +32,11 @@ module MailCatcher::Mail extend self
30
32
  charset TEXT,
31
33
  body BLOB,
32
34
  size INTEGER,
33
- created_at DATETIME DEFAULT CURRENT_DATETIME
35
+ created_at DATETIME DEFAULT CURRENT_DATETIME,
36
+ FOREIGN KEY (message_id) REFERENCES message (id) ON DELETE CASCADE
34
37
  )
35
38
  SQL
39
+ db.execute("PRAGMA foreign_keys = ON")
36
40
  end
37
41
  end
38
42
  end
@@ -41,7 +45,7 @@ module MailCatcher::Mail extend self
41
45
  @add_message_query ||= db.prepare("INSERT INTO message (sender, recipients, subject, source, type, size, created_at) VALUES (?, ?, ?, ?, ?, ?, datetime('now'))")
42
46
 
43
47
  mail = Mail.new(message[:source])
44
- @add_message_query.execute(message[:sender], message[:recipients].to_json, mail.subject, message[:source], mail.mime_type || 'text/plain', message[:source].length)
48
+ @add_message_query.execute(message[:sender], JSON.generate(message[:recipients]), mail.subject, message[:source], mail.mime_type || "text/plain", message[:source].length)
45
49
  message_id = db.last_insert_row_id
46
50
  parts = mail.all_parts
47
51
  parts = [mail] if parts.empty?
@@ -49,12 +53,12 @@ module MailCatcher::Mail extend self
49
53
  body = part.body.to_s
50
54
  # Only parts have CIDs, not mail
51
55
  cid = part.cid if part.respond_to? :cid
52
- add_message_part(message_id, cid, part.mime_type || 'text/plain', part.attachment? ? 1 : 0, part.filename, part.charset, body, body.length)
56
+ add_message_part(message_id, cid, part.mime_type || "text/plain", part.attachment? ? 1 : 0, part.filename, part.charset, body, body.length)
53
57
  end
54
58
 
55
59
  EventMachine.next_tick do
56
60
  message = MailCatcher::Mail.message message_id
57
- MailCatcher::Events::MessageAdded.push message
61
+ MailCatcher::Bus.push(type: "add", message: message)
58
62
  end
59
63
  end
60
64
 
@@ -69,25 +73,31 @@ module MailCatcher::Mail extend self
69
73
  end
70
74
 
71
75
  def messages
72
- @messages_query ||= db.prepare "SELECT id, sender, recipients, subject, size, created_at FROM message ORDER BY created_at DESC"
76
+ @messages_query ||= db.prepare "SELECT id, sender, recipients, subject, size, created_at FROM message ORDER BY created_at, id ASC"
73
77
  @messages_query.execute.map do |row|
74
78
  Hash[row.fields.zip(row)].tap do |message|
75
- message["recipients"] &&= ActiveSupport::JSON.decode message["recipients"]
79
+ message["recipients"] &&= JSON.parse(message["recipients"])
76
80
  end
77
81
  end
78
82
  end
79
83
 
80
84
  def message(id)
81
- @message_query ||= db.prepare "SELECT * FROM message WHERE id = ? LIMIT 1"
85
+ @message_query ||= db.prepare "SELECT id, sender, recipients, subject, size, type, created_at FROM message WHERE id = ? LIMIT 1"
82
86
  row = @message_query.execute(id).next
83
87
  row && Hash[row.fields.zip(row)].tap do |message|
84
- message["recipients"] &&= ActiveSupport::JSON.decode message["recipients"]
88
+ message["recipients"] &&= JSON.parse(message["recipients"])
85
89
  end
86
90
  end
87
91
 
92
+ def message_source(id)
93
+ @message_source_query ||= db.prepare "SELECT source FROM message WHERE id = ? LIMIT 1"
94
+ row = @message_source_query.execute(id).next
95
+ row && row.first
96
+ end
97
+
88
98
  def message_has_html?(id)
89
99
  @message_has_html_query ||= db.prepare "SELECT 1 FROM message_part WHERE message_id = ? AND is_attachment = 0 AND type IN ('application/xhtml+xml', 'text/html') LIMIT 1"
90
- (!!@message_has_html_query.execute(id).next) || ['text/html', 'application/xhtml+xml'].include?(message(id)["type"])
100
+ (!!@message_has_html_query.execute(id).next) || ["text/html", "application/xhtml+xml"].include?(message(id)["type"])
91
101
  end
92
102
 
93
103
  def message_has_plain?(id)
@@ -126,7 +136,7 @@ module MailCatcher::Mail extend self
126
136
  part ||= message_part_type(message_id, "application/xhtml+xml")
127
137
  part ||= begin
128
138
  message = message(message_id)
129
- message if message.present? and ['text/html', 'application/xhtml+xml'].include? message["type"]
139
+ message if message and ["text/html", "application/xhtml+xml"].include? message["type"]
130
140
  end
131
141
  end
132
142
 
@@ -135,7 +145,7 @@ module MailCatcher::Mail extend self
135
145
  end
136
146
 
137
147
  def message_part_cid(message_id, cid)
138
- @message_part_cid_query ||= db.prepare 'SELECT * FROM message_part WHERE message_id = ?'
148
+ @message_part_cid_query ||= db.prepare "SELECT * FROM message_part WHERE message_id = ?"
139
149
  @message_part_cid_query.execute(message_id).map do |row|
140
150
  Hash[row.fields.zip(row)]
141
151
  end.find do |part|
@@ -144,17 +154,30 @@ module MailCatcher::Mail extend self
144
154
  end
145
155
 
146
156
  def delete!
147
- @delete_messages_query ||= db.prepare 'DELETE FROM message'
148
- @delete_message_parts_query ||= db.prepare 'DELETE FROM message_part'
157
+ @delete_all_messages_query ||= db.prepare "DELETE FROM message"
158
+ @delete_all_messages_query.execute
149
159
 
150
- @delete_messages_query.execute and
151
- @delete_message_parts_query.execute
160
+ EventMachine.next_tick do
161
+ MailCatcher::Bus.push(type: "clear")
162
+ end
152
163
  end
153
164
 
154
165
  def delete_message!(message_id)
155
- @delete_messages_query ||= db.prepare 'DELETE FROM message WHERE id = ?'
156
- @delete_message_parts_query ||= db.prepare 'DELETE FROM message_part WHERE message_id = ?'
157
- @delete_messages_query.execute(message_id) and
158
- @delete_message_parts_query.execute(message_id)
166
+ @delete_messages_query ||= db.prepare "DELETE FROM message WHERE id = ?"
167
+ @delete_messages_query.execute(message_id)
168
+
169
+ EventMachine.next_tick do
170
+ MailCatcher::Bus.push(type: "remove", id: message_id)
171
+ end
172
+ end
173
+
174
+ def delete_older_messages!(count = MailCatcher.options[:messages_limit])
175
+ return if count.nil?
176
+ @older_messages_query ||= db.prepare "SELECT id FROM message WHERE id NOT IN (SELECT id FROM message ORDER BY created_at DESC LIMIT ?)"
177
+ @older_messages_query.execute(count).map do |row|
178
+ Hash[row.fields.zip(row)]
179
+ end.each do |message|
180
+ delete_message!(message["id"])
181
+ end
159
182
  end
160
183
  end
@@ -1,11 +1,16 @@
1
- require 'eventmachine'
1
+ # frozen_string_literal: true
2
+
3
+ require "eventmachine"
4
+
5
+ require "mail_catcher/mail"
2
6
 
3
7
  class MailCatcher::Smtp < EventMachine::Protocols::SmtpServer
4
8
  # We override EM's mail from processing to allow multiple mail-from commands
5
- # per [RFC 2821](http://tools.ietf.org/html/rfc2821#section-4.1.1.2)
9
+ # per [RFC 2821](https://tools.ietf.org/html/rfc2821#section-4.1.1.2)
6
10
  def process_mail_from sender
7
11
  if @state.include? :mail_from
8
12
  @state -= [:mail_from, :rcpt, :data]
13
+
9
14
  receive_reset
10
15
  end
11
16
 
@@ -18,38 +23,44 @@ class MailCatcher::Smtp < EventMachine::Protocols::SmtpServer
18
23
 
19
24
  def receive_reset
20
25
  @current_message = nil
26
+
21
27
  true
22
28
  end
23
29
 
24
30
  def receive_sender(sender)
31
+ # EventMachine SMTP advertises size extensions [https://tools.ietf.org/html/rfc1870]
32
+ # so strip potential " SIZE=..." suffixes from senders
33
+ sender = $` if sender =~ / SIZE=\d+\z/
34
+
25
35
  current_message[:sender] = sender
36
+
26
37
  true
27
38
  end
28
39
 
29
40
  def receive_recipient(recipient)
30
41
  current_message[:recipients] ||= []
31
42
  current_message[:recipients] << recipient
43
+
32
44
  true
33
45
  end
34
46
 
35
47
  def receive_data_chunk(lines)
36
- current_message[:source] ||= ""
37
- current_message[:source] << lines.join("\n")
48
+ current_message[:source] ||= +""
49
+
50
+ lines.each do |line|
51
+ current_message[:source] << line << "\r\n"
52
+ end
53
+
38
54
  true
39
55
  end
40
56
 
41
57
  def receive_message
42
58
  MailCatcher::Mail.add_message current_message
59
+ MailCatcher::Mail.delete_older_messages!
43
60
  puts "==> SMTP: Received message from '#{current_message[:sender]}' (#{current_message[:source].length} bytes)"
44
61
  true
45
- rescue
46
- puts "*** Error receiving message: #{current_message.inspect}"
47
- puts " Exception: #{$!}"
48
- puts " Backtrace:"
49
- $!.backtrace.each do |line|
50
- puts " #{line}"
51
- end
52
- puts " Please submit this as an issue at http://github.com/sj26/mailcatcher/issues"
62
+ rescue => exception
63
+ MailCatcher.log_exception("Error receiving message", @current_message, exception)
53
64
  false
54
65
  ensure
55
66
  @current_message = nil
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MailCatcher
2
- VERSION = "0.5.12"
4
+ VERSION = "0.8.1"
3
5
  end