mailcatcher 0.5.12 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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