better_opener 0.0.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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in better_opener.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,34 @@
1
+ = Better Opener
2
+
3
+ Preview mails and other notifications (sms for instance) in your browser
4
+ instead of actually sending them out. Inspired and almost similar to the
5
+ Letter Opener by Ryan Bates Better Opener this gem tries to be *better* by being
6
+ more universal and displaying desktop notifications (with the chrome plugin).
7
+
8
+ == Setup
9
+
10
+ Add the gem to your development environment and run the <tt>bundle install</tt> command to install it.
11
+
12
+ gem "better_opener", :group => :development
13
+
14
+ Set the delivery method in <tt>config/environments/development.rb</tt>
15
+
16
+ config.action_mailer.delivery_method = :letter_opener
17
+
18
+ Finally install the bundled Sinatra app as a subdirectory of your app by editing your <tt>config.ru</tt>:
19
+
20
+ map "/notification" do
21
+ run BetterOpener::Server
22
+ end
23
+
24
+
25
+
26
+ == Chrome Plugin
27
+
28
+ To take full advantage and get actual notifications, you will want to install
29
+ the accompanying chrome plugin. Just point it to the notification address you
30
+ set up above.
31
+
32
+
33
+
34
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "better_opener/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "better_opener"
7
+ s.version = BetterOpener::VERSION
8
+ s.authors = ["Kai Rubarth"]
9
+ s.email = ["kai@doxter.de"]
10
+ s.homepage = "http://github.com/learnjin/better_opener"
11
+ s.summary = %q{A better way of Previewing mail in your browser instead of sending it.}
12
+ s.description = %q{When mails or messages are sent from your application, Better Opener lets you preview the rendered messages in your browser instead of delivering them.}
13
+
14
+ s.rubyforge_project = "better_opener"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "sinatra-contrib"
23
+
24
+ s.add_dependency "data_mapper", ">= 1.2"
25
+ s.add_dependency "dm-sqlite-adapter"
26
+ s.add_dependency "tilt"
27
+ s.add_dependency "haml"
28
+
29
+ end
30
+
31
+
32
+
data/config.ru ADDED
@@ -0,0 +1,4 @@
1
+ require 'better_opener'
2
+
3
+ run BetterOpener::Server
4
+
@@ -0,0 +1,87 @@
1
+ require "better_opener/version"
2
+
3
+ require 'data_mapper'
4
+ require 'time'
5
+ require 'tilt'
6
+ require 'rack/mime'
7
+
8
+ module BetterOpener
9
+
10
+ class Notification
11
+ include DataMapper::Resource
12
+ property :id, Serial
13
+ property :subject, String
14
+ property :body, Text
15
+ property :created_at, DateTime
16
+ property :category, String
17
+ end
18
+
19
+ extend self
20
+
21
+ def db=(server)
22
+ @db = server
23
+ end
24
+
25
+ def db
26
+ return @db if @db
27
+ self.db = DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/development.db")
28
+ DataMapper.auto_upgrade!
29
+ self.db
30
+ end
31
+
32
+ def get_all_notifications
33
+ db && BetterOpener::Notification.all(:order => [:id.desc])
34
+ end
35
+
36
+ def get_notification(id)
37
+ db && BetterOpener::Notification.get(id)
38
+ end
39
+
40
+
41
+ def add_notification(category, subject, body)
42
+ db
43
+ n = BetterOpener::Notification.new :category => category, :subject => subject, :body => body, :created_at => Time.now
44
+ n.save
45
+ end
46
+
47
+ def email_template_path
48
+ File.expand_path('../better_opener/email.html.erb', __FILE__)
49
+ end
50
+
51
+ def email_template
52
+ Tilt.new(email_template_path)
53
+ end
54
+
55
+ def render_email(name, mail, format = nil)
56
+ body_part = mail
57
+
58
+ if mail.multipart?
59
+ content_type = Rack::Mime.mime_type(format)
60
+ body_part = mail.parts.find { |part| part.content_type.match(content_type) } || mail.parts.first
61
+ end
62
+
63
+ email_template.render(Object.new, :name => name, :mail => mail, :body_part => body_part)
64
+ end
65
+
66
+
67
+ def sms_template_path
68
+ File.expand_path('../better_opener/sms.html.erb', __FILE__)
69
+ end
70
+
71
+ def sms_template
72
+ Tilt.new(sms_template_path)
73
+ end
74
+
75
+ def render_sms(name, sms, format = nil)
76
+ sms_template.render(Object.new, :name => name, :sms => sms)
77
+ end
78
+
79
+
80
+ end
81
+
82
+ require 'better_opener/delivery_method'
83
+ require 'better_opener/server'
84
+ require "better_opener/railtie" if defined? Rails
85
+ require "better_opener/sms_gateway_adapter" if defined? SmsGateway
86
+
87
+
@@ -0,0 +1,13 @@
1
+ module BetterOpener
2
+ class DeliveryMethod
3
+
4
+ def initialize(options = {})
5
+ end
6
+
7
+ def deliver!(mail)
8
+ BetterOpener.add_notification("email", mail.subject, BetterOpener.render_email('NAME', mail))
9
+ end
10
+ end
11
+
12
+ end
13
+
@@ -0,0 +1,88 @@
1
+ <head>
2
+ <meta http-equiv="Content-Type" content="text/html; charset=<%= body_part.charset %>" />
3
+ </head>
4
+ <style type="text/css">
5
+ #message_headers {
6
+ position: absolute;
7
+ top: 0px;
8
+ left: 0;
9
+ width: 100%;
10
+ height: 85px;
11
+ padding: 10px 0 0 0;
12
+ margin: 0;
13
+ background: #fff;
14
+ font-size: 12px;
15
+ font-family: "Lucida Grande";
16
+ border-bottom: 1px solid #dedede;
17
+ overflow: hidden;
18
+ }
19
+
20
+ #message_headers dl {
21
+ margin: 0;
22
+ padding: 0;
23
+ }
24
+
25
+ #message_headers dt {
26
+ width: 60px;
27
+ padding: 1px;
28
+ float: left;
29
+ text-align: right;
30
+ font-weight: bold;
31
+ color: #7f7f7f;
32
+ }
33
+
34
+ #message_headers dd {
35
+ margin-left: 70px;
36
+ padding: 1px;
37
+ }
38
+
39
+ #message_headers p.alternate {
40
+ position: absolute;
41
+ top: 0;
42
+ right: 15px;
43
+ }
44
+
45
+ #message_headers p.alternate a {
46
+ color: #09c;
47
+ }
48
+
49
+ pre#message_body {
50
+ padding: 10px;
51
+ white-space: pre-wrap;
52
+ }
53
+
54
+ body {
55
+ margin-top: 96px;
56
+ }
57
+ </style>
58
+ <div id="message_headers">
59
+ <dl>
60
+ <dt>From:</dt>
61
+ <dd><%= mail.from %></dd>
62
+
63
+ <dt>Subject:</dt>
64
+ <dd><strong><%= mail.subject %></strong></dd>
65
+
66
+ <dt>Date:</dt>
67
+ <dd><%= Time.now.strftime("%b %e, %Y %I:%M:%S %p %Z") %></dd>
68
+
69
+ <dt>To:</dt>
70
+ <dd><%= mail.to %></dd>
71
+ </dl>
72
+
73
+ <% if mail.multipart? %>
74
+ <p class="alternate">
75
+ <% if body_part.content_type && body_part.content_type.match(/text\/html/) %>
76
+ <a href="<%= name %>.txt">View plain text version</a>
77
+ <% else %>
78
+ <a href="<%= name %>.html">View HTML version</a>
79
+ <% end %>
80
+ </p>
81
+ <% end %>
82
+ </div>
83
+
84
+ <% if body_part.content_type && body_part.content_type.match(/text\/html/) %>
85
+ <%= body_part.body %>
86
+ <% else %>
87
+ <pre id="message_body"><%= body_part.body %></pre>
88
+ <% end %>
@@ -0,0 +1,8 @@
1
+ module BetterOpener
2
+ class Railtie < Rails::Railtie
3
+ initializer "better_opener.add_delivery_method" do
4
+ ActionMailer::Base.add_delivery_method :better_opener, BetterOpener::DeliveryMethod
5
+ end
6
+ end
7
+ end
8
+
@@ -0,0 +1,60 @@
1
+ require 'rubygems' if RUBY_VERSION < '1.9'
2
+ require 'sinatra'
3
+ #require 'sinatra/reloader' if development?
4
+ require 'haml'
5
+ require 'data_mapper'
6
+ require 'better_opener'
7
+
8
+ module BetterOpener
9
+
10
+ class Server < Sinatra::Base
11
+ #configure :development do
12
+ # register Sinatra::Reloader
13
+ #nd
14
+
15
+ helpers do
16
+ include Rack::Utils
17
+ alias_method :h, :escape_html
18
+
19
+ def url_path(*path_parts)
20
+ path = [ path_prefix, path_parts ].join("/").squeeze('/')
21
+ request.scheme + "://" + request.host_with_port + path
22
+ end
23
+ alias_method :u, :url_path
24
+
25
+ def path_prefix
26
+ request.script_name
27
+ end
28
+
29
+ end
30
+
31
+ dir = File.dirname(File.expand_path(__FILE__))
32
+
33
+ set :views, "#{dir}/server/views"
34
+ set :public, "#{dir}/server/public"
35
+ set :static, true
36
+
37
+ get "/" do
38
+ @messages = BetterOpener.get_all_notifications
39
+ haml :index
40
+ end
41
+
42
+ get "/purge" do
43
+ BetterOpener::Notification.all.destroy
44
+ redirect u('/')
45
+ end
46
+
47
+ get "/:id" do
48
+ @message = BetterOpener.get_notification(params[:id])
49
+ @message.body
50
+ end
51
+
52
+ get "/feed/atom", :provides => [:atom] do
53
+ @messages = BetterOpener.get_all_notifications
54
+ content_type 'application/rss+xml'
55
+ haml(:atom, :format => :xhtml, :escape_html => true, :layout => false)
56
+ end
57
+
58
+ end
59
+ end
60
+
@@ -0,0 +1,17 @@
1
+ !!! XML
2
+ %feed{:version=> "0.3", :xmlns=> "http://purl.org/atom/ns#"}
3
+ %title Notification Outbox
4
+ %tagline Messages in your Outbox
5
+ %fullcount= @messages.size
6
+ %link{:rel=>"alternate", :href => u("/"), :type => "text/html"}
7
+ %modified= @messages.size > 0 ? @messages.first.created_at : Time.now
8
+ - for message in @messages
9
+ %entry
10
+ %title= message.subject
11
+ %summary= "#{message.subject} ..."
12
+ %link{:rel => "alternate", :href => u("/#{message.id}")}
13
+ %modified= message.created_at
14
+ %issued= message.created_at
15
+ %category= message.category
16
+ %id= message.id
17
+
@@ -0,0 +1,14 @@
1
+ %h1= "Outgoing Notifications"
2
+ %p
3
+ %a{:href => u("/purge")}= "Purge All!"
4
+
5
+ %ul
6
+ - for m in @messages
7
+ %li
8
+ = m.category + ": "
9
+ %em
10
+ %a{:href => u("/#{m.id}") }= m.subject
11
+
12
+
13
+
14
+
@@ -0,0 +1,4 @@
1
+ %h1= @message.subject
2
+ %h2= @message.category
3
+ %p= @message.body
4
+
@@ -0,0 +1,99 @@
1
+ <head>
2
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
3
+ </head>
4
+ <style type="text/css">
5
+ #message_headers {
6
+ position: absolute;
7
+ top: 0px;
8
+ left: 0;
9
+ width: 100%;
10
+ height: 65px;
11
+ padding: 10px 0 0 0;
12
+ margin: 0;
13
+ background: #fff;
14
+ font-size: 12px;
15
+ font-family: "Lucida Grande";
16
+ /*border-bottom: 1px solid #dedede;*/
17
+ overflow: hidden;
18
+ }
19
+
20
+ #message_headers dl {
21
+ margin: 0;
22
+ padding: 0;
23
+ }
24
+
25
+ #message_headers dt {
26
+ width: 60px;
27
+ padding: 1px;
28
+ float: left;
29
+ text-align: right;
30
+ font-weight: bold;
31
+ color: #7f7f7f;
32
+ }
33
+
34
+ #message_headers dd {
35
+ margin-left: 70px;
36
+ padding: 1px;
37
+ }
38
+
39
+ #message_headers p.alternate {
40
+ position: absolute;
41
+ top: 0;
42
+ right: 15px;
43
+ }
44
+
45
+ #message_headers p.alternate a {
46
+ color: #09c;
47
+ }
48
+
49
+ pre#message_body {
50
+ padding: 10px;
51
+ white-space: pre-wrap;
52
+ }
53
+
54
+ body {
55
+ margin-top: 96px;
56
+ }
57
+
58
+ #sms_body{
59
+ }
60
+
61
+ div.outcome {
62
+ background-color: #A3E6A5;
63
+ border-top-left-radius: 0;
64
+ -moz-border-radius-topleft: 0;
65
+ margin-left: 2em;
66
+ }
67
+
68
+ .message {
69
+ border: 1px solid #ccc;
70
+ border-radius: 10px;
71
+ -moz-border-radius: 10px;
72
+ padding: .5em;
73
+ margin-bottom: 1em;
74
+ width: 500px;
75
+ }
76
+
77
+ </style>
78
+ <div id="message_headers">
79
+ <dl>
80
+ <dt>From:</dt>
81
+ <dd><%= sms.from %></dd>
82
+
83
+ <dt>To:</dt>
84
+ <dd><%= sms.to %></dd>
85
+
86
+ <dt>Date:</dt>
87
+ <dd><%= Time.now.strftime("%b %e, %Y %I:%M:%S %p %Z") %></dd>
88
+
89
+ </dl>
90
+
91
+ </div>
92
+
93
+ <div id="sms_body">
94
+ <div class="outcome message">
95
+ <%= sms.text %>
96
+ </div>
97
+ </div>
98
+
99
+
@@ -0,0 +1,22 @@
1
+ require 'sms_gateway'
2
+
3
+ module SmsGateway
4
+
5
+ module Adapters
6
+ class BetterOpener
7
+
8
+ def initialize(config={})
9
+ @config = {:from => SmsGateway::Base.from }
10
+ @config.merge!(config)
11
+ end
12
+
13
+ def send_sms(sms)
14
+ options = @config.merge({:to => sms.to, :message => sms.text })
15
+ ::BetterOpener.add_notification("sms", sms.from, ::BetterOpener.render_sms('sms', sms) )
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+
22
+
@@ -0,0 +1,3 @@
1
+ module BetterOpener
2
+ VERSION = "0.0.1"
3
+ end
data/lib/test.ru ADDED
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'rack'
3
+ require 'better_opener/server'
4
+
5
+ map "/notifications" do
6
+ run BetterOpener::Server
7
+ end
8
+
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: better_opener
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Kai Rubarth
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-03-02 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: sinatra-contrib
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: data_mapper
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 11
43
+ segments:
44
+ - 1
45
+ - 2
46
+ version: "1.2"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: dm-sqlite-adapter
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: tilt
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: haml
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :runtime
90
+ version_requirements: *id005
91
+ description: When mails or messages are sent from your application, Better Opener lets you preview the rendered messages in your browser instead of delivering them.
92
+ email:
93
+ - kai@doxter.de
94
+ executables: []
95
+
96
+ extensions: []
97
+
98
+ extra_rdoc_files: []
99
+
100
+ files:
101
+ - .gitignore
102
+ - Gemfile
103
+ - README.rdoc
104
+ - Rakefile
105
+ - better_opener.gemspec
106
+ - config.ru
107
+ - lib/better_opener.rb
108
+ - lib/better_opener/delivery_method.rb
109
+ - lib/better_opener/email.html.erb
110
+ - lib/better_opener/railtie.rb
111
+ - lib/better_opener/server.rb
112
+ - lib/better_opener/server/views/atom.haml
113
+ - lib/better_opener/server/views/index.haml
114
+ - lib/better_opener/server/views/show.haml
115
+ - lib/better_opener/sms.html.erb
116
+ - lib/better_opener/sms_gateway_adapter.rb
117
+ - lib/better_opener/version.rb
118
+ - lib/test.ru
119
+ homepage: http://github.com/learnjin/better_opener
120
+ licenses: []
121
+
122
+ post_install_message:
123
+ rdoc_options: []
124
+
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ hash: 3
133
+ segments:
134
+ - 0
135
+ version: "0"
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ hash: 3
142
+ segments:
143
+ - 0
144
+ version: "0"
145
+ requirements: []
146
+
147
+ rubyforge_project: better_opener
148
+ rubygems_version: 1.8.10
149
+ signing_key:
150
+ specification_version: 3
151
+ summary: A better way of Previewing mail in your browser instead of sending it.
152
+ test_files: []
153
+