2010-10-27 15:12:26 -04:00
|
|
|
require 'sinatra'
|
|
|
|
require 'pathname'
|
2011-10-07 10:16:17 -04:00
|
|
|
require 'net/http'
|
|
|
|
require 'uri'
|
2010-10-27 15:12:26 -04:00
|
|
|
|
|
|
|
require 'skinny'
|
|
|
|
|
|
|
|
class Sinatra::Request
|
2010-11-03 23:15:12 -04:00
|
|
|
include Skinny::Helpers
|
2010-10-27 15:12:26 -04:00
|
|
|
end
|
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
class MailCatcher::Web < Sinatra::Base
|
2012-10-28 22:26:14 -04:00
|
|
|
set :root, File.expand_path("#{__FILE__}/../../..")
|
2011-10-09 03:45:23 -04:00
|
|
|
set :haml, :format => :html5
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
get '/' do
|
|
|
|
haml :index
|
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
delete '/' do
|
|
|
|
MailCatcher.quit!
|
|
|
|
status 204
|
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
get '/messages' do
|
|
|
|
if request.websocket?
|
|
|
|
request.websocket!(
|
|
|
|
:on_start => proc do |websocket|
|
|
|
|
subscription = MailCatcher::Events::MessageAdded.subscribe { |message| websocket.send_message message.to_json }
|
|
|
|
websocket.on_close do |websocket|
|
|
|
|
MailCatcher::Events::MessageAdded.unsubscribe subscription
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
else
|
|
|
|
MailCatcher::Mail.messages.to_json
|
2010-10-27 15:12:26 -04:00
|
|
|
end
|
2011-10-09 03:45:23 -04:00
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
delete '/messages' do
|
|
|
|
MailCatcher::Mail.delete!
|
|
|
|
status 204
|
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
get '/messages/:id.json' do
|
|
|
|
id = params[:id].to_i
|
|
|
|
if message = MailCatcher::Mail.message(id)
|
|
|
|
message.merge({
|
|
|
|
"formats" => [
|
|
|
|
"source",
|
|
|
|
("html" if MailCatcher::Mail.message_has_html? id),
|
|
|
|
("plain" if MailCatcher::Mail.message_has_plain? id),
|
2013-07-13 10:15:41 -04:00
|
|
|
("lessplain" if MailCatcher::Mail.message_has_plain? id),
|
2011-10-09 03:45:23 -04:00
|
|
|
].compact,
|
|
|
|
"attachments" => MailCatcher::Mail.message_attachments(id).map do |attachment|
|
2011-12-04 09:26:09 -05:00
|
|
|
attachment.merge({"href" => "/messages/#{escape(id)}/parts/#{escape(attachment['cid'])}"})
|
2011-10-09 03:45:23 -04:00
|
|
|
end,
|
|
|
|
}).to_json
|
|
|
|
else
|
|
|
|
not_found
|
2010-10-27 15:12:26 -04:00
|
|
|
end
|
2011-10-09 03:45:23 -04:00
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
get '/messages/:id.html' do
|
|
|
|
id = params[:id].to_i
|
|
|
|
if part = MailCatcher::Mail.message_part_html(id)
|
|
|
|
content_type part["type"], :charset => (part["charset"] || "utf8")
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
body = part["body"]
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
# Rewrite body to link to embedded attachments served by cid
|
|
|
|
body.gsub! /cid:([^'"> ]+)/, "#{id}/parts/\\1"
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
# Rewrite body to open links in a new window
|
|
|
|
body.gsub! /<a\s+/, '<a target="_blank" '
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
body
|
|
|
|
else
|
|
|
|
not_found
|
2010-10-27 15:12:26 -04:00
|
|
|
end
|
2011-10-09 03:45:23 -04:00
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
get "/messages/:id.plain" do
|
|
|
|
id = params[:id].to_i
|
|
|
|
if part = MailCatcher::Mail.message_part_plain(id)
|
|
|
|
content_type part["type"], :charset => (part["charset"] || "utf8")
|
|
|
|
part["body"]
|
|
|
|
else
|
|
|
|
not_found
|
2010-10-27 15:12:26 -04:00
|
|
|
end
|
2011-10-09 03:45:23 -04:00
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2013-07-13 10:15:41 -04:00
|
|
|
get "/messages/:id.lessplain" do
|
|
|
|
id = params[:id].to_i
|
|
|
|
if part = MailCatcher::Mail.message_part_plain(id)
|
|
|
|
content_type "text/html", :charset => (part["charset"] || "utf8")
|
|
|
|
body = part["body"]
|
|
|
|
body.gsub!(/((http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?)/, '<a href="\\1">\\1</a>')
|
|
|
|
body.gsub!("\n", "<br/>\n")
|
|
|
|
"<html><body>" + body + "</body></html>"
|
|
|
|
else
|
|
|
|
not_found
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
get "/messages/:id.source" do
|
|
|
|
id = params[:id].to_i
|
|
|
|
if message = MailCatcher::Mail.message(id)
|
|
|
|
content_type "text/plain"
|
|
|
|
message["source"]
|
|
|
|
else
|
|
|
|
not_found
|
2010-10-27 15:12:26 -04:00
|
|
|
end
|
2011-10-09 03:45:23 -04:00
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
get "/messages/:id.eml" do
|
|
|
|
id = params[:id].to_i
|
|
|
|
if message = MailCatcher::Mail.message(id)
|
|
|
|
content_type "message/rfc822"
|
|
|
|
message["source"]
|
|
|
|
else
|
|
|
|
not_found
|
2011-05-27 09:40:16 -04:00
|
|
|
end
|
2011-10-09 03:45:23 -04:00
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
get "/messages/:id/parts/:cid" do
|
|
|
|
id = params[:id].to_i
|
|
|
|
if part = MailCatcher::Mail.message_part_cid(id, params[:cid])
|
|
|
|
content_type part["type"], :charset => (part["charset"] || "utf8")
|
|
|
|
attachment part["filename"] if part["is_attachment"] == 1
|
|
|
|
body part["body"].to_s
|
|
|
|
else
|
|
|
|
not_found
|
2010-10-27 15:12:26 -04:00
|
|
|
end
|
2011-10-09 03:45:23 -04:00
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
get "/messages/:id/analysis.?:format?" do
|
|
|
|
id = params[:id].to_i
|
|
|
|
if part = MailCatcher::Mail.message_part_html(id)
|
|
|
|
# TODO: Server-side cache? Make the browser cache based on message create time? Hmm.
|
|
|
|
uri = URI.parse("http://api.getfractal.com/api/v2/validate#{"/format/#{params[:format]}" if params[:format].present?}")
|
2011-10-10 02:23:26 -04:00
|
|
|
response = Net::HTTP.post_form(uri, :api_key => "5c463877265251386f516f7428", :html => part["body"])
|
2011-10-09 03:45:23 -04:00
|
|
|
content_type ".#{params[:format]}" if params[:format].present?
|
|
|
|
body response.body
|
|
|
|
else
|
|
|
|
not_found
|
2011-10-07 10:16:17 -04:00
|
|
|
end
|
2011-10-09 03:45:23 -04:00
|
|
|
end
|
2011-10-07 10:16:17 -04:00
|
|
|
|
2012-10-24 18:45:26 -04:00
|
|
|
delete '/messages/:id' do
|
|
|
|
id = params[:id].to_i
|
|
|
|
if message = MailCatcher::Mail.message(id)
|
|
|
|
MailCatcher::Mail.delete_message!(id)
|
|
|
|
status 204
|
|
|
|
else
|
|
|
|
not_found
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-10-09 03:45:23 -04:00
|
|
|
not_found do
|
|
|
|
"<html><body><h1>No Dice</h1><p>The message you were looking for does not exist, or doesn't have content of this type.</p></body></html>"
|
2010-10-27 15:12:26 -04:00
|
|
|
end
|
2011-06-09 23:21:39 -04:00
|
|
|
end
|