mailcatcher 0.8.0 → 0.10.0.alpha1

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
2
  SHA256:
3
- metadata.gz: c7bd063a1a2ccd3cd8e3cf6a8ee495acafdca0d90ab2c3a16e4b62f6180bb9aa
4
- data.tar.gz: 62cec0bcce04b0f74e200c9f47d8ab157ab889060377137f840f2717923c3f3f
3
+ metadata.gz: 1aa3aa753b23a9b3bd275630bdcc3f327c4b20ce473d588a27dce358227402f1
4
+ data.tar.gz: 9501f6236cca02daa9856dbf1d9465710c2680cb2854e7c2c65034d04cc76b1a
5
5
  SHA512:
6
- metadata.gz: f532803f11699a109ce7be2ec7c35251dfc15e448cb6d90c65fc5a1db7757a5924883dff6259fec7dbf3e3139ad41815a3a29e4c545575e252c40c9c29b50ba3
7
- data.tar.gz: 9cfadf47007c3fe0362ce6c7111e688539caaff2dd32da84ae5af78840d2c67860aceb54f46cf7c511d4700f21a056e8218a0cc90f174ba4a8cacb9130e775f0
6
+ metadata.gz: f64c5dba1a1283516cb528c786dda5955ea0839aa9ee213dfc7953d96295ce523042a89052f3f524c2b04a096a85fc50032c156bf25d10f215e230efbf4c68a4
7
+ data.tar.gz: f2173054df228613688e6f478f3b81b50b6bab836318a6beb27dfdc07974b8a6aa406e56087b369d8a43c4adeac942a34fcf5c82f62905f50413f806585ed1e0
checksums.yaml.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -32,17 +32,30 @@ Use `mailcatcher --help` to see the command line options.
32
32
 
33
33
  ```
34
34
  Usage: mailcatcher [options]
35
+
36
+ MailCatcher v0.8.0
37
+
35
38
  --ip IP Set the ip address of both servers
36
39
  --smtp-ip IP Set the ip address of the smtp server
37
40
  --smtp-port PORT Set the port of the smtp server
38
41
  --http-ip IP Set the ip address of the http server
39
42
  --http-port PORT Set the port address of the http server
43
+ --messages-limit COUNT Only keep up to COUNT most recent messages
40
44
  --http-path PATH Add a prefix to all HTTP paths
41
45
  --no-quit Don't allow quitting the process
42
46
  -f, --foreground Run in the foreground
43
47
  -b, --browse Open web browser
44
48
  -v, --verbose Be more verbose
45
49
  -h, --help Display this help information
50
+ --version Display the current version
51
+ ```
52
+
53
+ ### Upgrading
54
+
55
+ Upgrading works the same as installation:
56
+
57
+ ```
58
+ gem install mailcatcher
46
59
  ```
47
60
 
48
61
  ### Ruby
@@ -64,7 +77,7 @@ gem install thin -v 1.5.1 -- --with-cflags="-Wno-error=implicit-function-declara
64
77
 
65
78
  ### Bundler
66
79
 
67
- Please don't put mailcatcher into your Gemfile. It will conflict with your applications gems at some point.
80
+ Please don't put mailcatcher into your Gemfile. It will conflict with your application's gems at some point.
68
81
 
69
82
  Instead, pop a note in your README stating you use mailcatcher, and to run `gem install mailcatcher` then `mailcatcher` to get started.
70
83
 
@@ -112,9 +125,32 @@ if DEBUG:
112
125
  EMAIL_USE_TLS = False
113
126
  ```
114
127
 
128
+ ### Docker
129
+
130
+ There is a Docker image available [on Docker Hub](https://hub.docker.com/r/sj26/mailcatcher):
131
+
132
+ ```
133
+ $ docker run -p 1080 -p 1025 sj26/mailcatcher
134
+ Unable to find image 'sj26/mailcatcher:latest' locally
135
+ latest: Pulling from sj26/mailcatcher
136
+ 8c6d1654570f: Already exists
137
+ f5649d186f41: Already exists
138
+ b850834ea1df: Already exists
139
+ d6ac1a07fd46: Pull complete
140
+ b609298bc3c9: Pull complete
141
+ ab05825ece51: Pull complete
142
+ Digest: sha256:b17c45de08a0a82b012d90d4bd048620952c475f5655c61eef373318de6c0855
143
+ Status: Downloaded newer image for sj26/mailcatcher:latest
144
+ Starting MailCatcher v0.9.0
145
+ ==> smtp://0.0.0.0:1025
146
+ ==> http://0.0.0.0:1080
147
+ ```
148
+
149
+ How those ports appear and can be accessed may vary based on your Docker configuration. For example, your may need to use `http://127.0.0.1:1080` etc instead of the listed address. But MailCatcher will run and listen to those ports on all IPs it can from within the Docker container.
150
+
115
151
  ### API
116
152
 
117
- 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`.
153
+ 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/parts/:cid` for individual attachments by CID, or the whole message with `/messages/:id.source`.
118
154
 
119
155
  ## Caveats
120
156
 
@@ -36,7 +36,7 @@ module MailCatcher::Mail extend self
36
36
  FOREIGN KEY (message_id) REFERENCES message (id) ON DELETE CASCADE
37
37
  )
38
38
  SQL
39
- db.foreign_keys = true
39
+ db.execute("PRAGMA foreign_keys = ON")
40
40
  end
41
41
  end
42
42
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MailCatcher
4
- VERSION = "0.8.0"
4
+ VERSION = "0.10.0.alpha1"
5
5
  end
@@ -4,14 +4,31 @@ require "pathname"
4
4
  require "net/http"
5
5
  require "uri"
6
6
 
7
+ require "faye/websocket"
7
8
  require "sinatra"
8
- require "skinny"
9
9
 
10
10
  require "mail_catcher/bus"
11
11
  require "mail_catcher/mail"
12
12
 
13
+ Faye::WebSocket.load_adapter("thin")
14
+
15
+ # Faye's adapter isn't smart enough to close websockets when thin is stopped,
16
+ # so we teach it to do so.
17
+ class Thin::Backends::Base
18
+ alias :thin_stop :stop
19
+
20
+ def stop
21
+ thin_stop
22
+ @connections.each_value do |connection|
23
+ if connection.socket_stream
24
+ connection.socket_stream.close_connection_after_writing
25
+ end
26
+ end
27
+ end
28
+ end
29
+
13
30
  class Sinatra::Request
14
- include Skinny::Helpers
31
+ include Faye::WebSocket::Adapter
15
32
  end
16
33
 
17
34
  module MailCatcher
@@ -62,20 +79,24 @@ module MailCatcher
62
79
 
63
80
  get "/messages" do
64
81
  if request.websocket?
65
- request.websocket!(
66
- :on_start => proc do |websocket|
67
- bus_subscription = MailCatcher::Bus.subscribe do |message|
68
- begin
69
- websocket.send_message(JSON.generate(message))
70
- rescue => exception
71
- MailCatcher.log_exception("Error sending message through websocket", message, exception)
72
- end
82
+ bus_subscription = nil
83
+
84
+ ws = Faye::WebSocket.new(request.env)
85
+ ws.on(:open) do |_|
86
+ bus_subscription = MailCatcher::Bus.subscribe do |message|
87
+ begin
88
+ ws.send(JSON.generate(message))
89
+ rescue => exception
90
+ MailCatcher.log_exception("Error sending message through websocket", message, exception)
73
91
  end
92
+ end
93
+ end
74
94
 
75
- websocket.on_close do |*|
76
- MailCatcher::Bus.unsubscribe bus_subscription
77
- end
78
- end)
95
+ ws.on(:close) do |_|
96
+ MailCatcher::Bus.unsubscribe(bus_subscription) if bus_subscription
97
+ end
98
+
99
+ ws.rack_response
79
100
  else
80
101
  content_type :json
81
102
  JSON.generate(Mail.messages)
data/lib/mail_catcher.rb CHANGED
@@ -38,10 +38,10 @@ module MailCatcher extend self
38
38
  end
39
39
 
40
40
  def windows?
41
- RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
41
+ RbConfig::CONFIG["host_os"].match?(/mswin|mingw/)
42
42
  end
43
43
 
44
- def browseable?
44
+ def browsable?
45
45
  windows? or which? "open"
46
46
  end
47
47
 
@@ -134,7 +134,7 @@ module MailCatcher extend self
134
134
  end
135
135
  end
136
136
 
137
- if browseable?
137
+ if browsable?
138
138
  parser.on("-b", "--browse", "Open web browser") do
139
139
  options[:browse] = true
140
140
  end
@@ -185,13 +185,19 @@ module MailCatcher extend self
185
185
  end
186
186
 
187
187
  # Let Thin set itself up inside our EventMachine loop
188
- # (Skinny/WebSockets just works on the inside)
188
+ # Faye connections are hijacked but continue to be supervised by thin
189
189
  rescue_port options[:http_port] do
190
- Thin::Server.start(options[:http_ip], options[:http_port], Web)
190
+ Thin::Server.start(options[:http_ip], options[:http_port], Web, signals: false)
191
191
  puts "==> #{http_url}"
192
192
  end
193
193
 
194
- # Open the web browser before detatching console
194
+ # Make sure we quit nicely when asked
195
+ # We need to handle outside the trap context, hence the timer
196
+ trap("INT") { EM.add_timer(0) { quit! } }
197
+ trap("TERM") { EM.add_timer(0) { quit! } }
198
+ trap("QUIT") { EM.add_timer(0) { quit! } } unless windows?
199
+
200
+ # Open the web browser before detaching console
195
201
  if options[:browse]
196
202
  EventMachine.next_tick do
197
203
  browse http_url