resque-maktoub 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,55 @@
1
+ = Maktoub
2
+
3
+ Maktoub is a Ruby on Rails engine for email newsletters.
4
+ * Write your newsletter as you would write any view (erb partial)
5
+ * Maktoub sends your email in multipart as both html and text
6
+
7
+
8
+ == Installation
9
+
10
+ # Add this line to your Gemfile
11
+ gem 'resque-maktoub'
12
+
13
+ Then 'bundle install'
14
+
15
+ == Usage
16
+
17
+ === Configuration
18
+
19
+ You can run 'rails generate maktoub:config' to generate the configuration file. This task creates a matkoub.rb initializer file (in config/initializer)
20
+ Follow instructions inside the file to configure it the way you want.
21
+
22
+ === Authoring
23
+
24
+ Create a newsletter as a normal view partial in app/views/maktoub/newsletters/.
25
+ The subject of the newsletter will be automatically deduced from the partial's name.
26
+
27
+ === Editing Styles
28
+
29
+ Create a view partial in app/views/layouts/maktoub/_styles.erb. Note that this completely overrides the styles that come with maktoub.
30
+ You can copy the built-in styles and override them.
31
+
32
+ === Sending messages
33
+ Maktoub comes with two rake tasks to allow you to:
34
+ * send a test message to the "from" address of your newsletter.
35
+
36
+ rake maktoub:test['name_of_my_newsletter_partial']
37
+
38
+ * publish the newsletter to all your subscribers. If you have delayed_job installed then it will use it to deliver each email as a background job
39
+
40
+ rake maktoub:mail['name_of_my_newsletter_parial']
41
+
42
+
43
+ Alternatively you have access to a Maktoub::NewsletterMailer ActionMailer object with a publish method
44
+ Maktoub::NewsletterMail.publish('my_newsletter_partial', :name => 'User name', :email => 'user@example.com')
45
+
46
+ === View in browser
47
+ To be able to view your newsletter in a browser add it to routes.rb.
48
+ # mount the engine at a path of your choice.
49
+ # you would access the newsletter at: http://example.com/newsletter/my_awesome_newletter
50
+ mount Maktoub::Engine => "/"
51
+
52
+ == Contributing
53
+ Send a pull request including documentation changes and tests.
54
+
55
+
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Maktoub'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+ Bundler::GemHelper.install_tasks
28
+
29
+ require 'rspec/core/rake_task'
30
+
31
+ RSpec::Core::RakeTask.new(:spec)
32
+ task :default => :spec
33
+
34
+
35
+ #Rake::TestTask.new(:test) do |t|
36
+ # t.libs << 'lib'
37
+ # t.libs << 'spec'
38
+ # t.pattern = 'spec/**/*_spec.rb'
39
+ # t.verbose = false
40
+ #end
41
+
42
+
43
+ #task :default => :test
@@ -0,0 +1,9 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ //= require jquery
8
+ //= require jquery_ujs
9
+ //= require_tree .
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,7 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require_self
6
+ *= require_tree .
7
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ module Maktoub
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ module Maktoub
2
+ class ArchivesController < ApplicationController
3
+ layout 'maktoub/newsletter_mailer'
4
+ def show
5
+ @archive = true
6
+ template = params[:newsletter] || 'readme'
7
+ @subject = template.titleize
8
+
9
+ render "maktoub/newsletters/#{template}"
10
+ end
11
+
12
+ end
13
+ end
14
+
@@ -0,0 +1,20 @@
1
+ module Maktoub
2
+ class SubscribersController < ApplicationController
3
+ layout 'maktoub/application'
4
+
5
+ def edit
6
+
7
+ end
8
+
9
+ def update
10
+ if params[:email].blank?
11
+ @message = "email is required"
12
+ render :edit, :status => 400
13
+ else
14
+ Maktoub.unsubscribe params[:email]
15
+ end
16
+ end
17
+
18
+ end
19
+ end
20
+
@@ -0,0 +1,4 @@
1
+ module Maktoub
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Maktoub
2
+ module ArchivesHelper
3
+ end
4
+ end
@@ -0,0 +1,34 @@
1
+ require 'premailer'
2
+
3
+ module Maktoub
4
+ class NewsletterMailer < ActionMailer::Base
5
+ include Resque::Mailer
6
+
7
+ default from: Maktoub.from,
8
+ parts_order: [ "text/html", "text/plain" ]
9
+
10
+ default_url_options[:host] = Maktoub.home_domain
11
+
12
+ def publish(newsletter_name, params)
13
+ @name = params[:name]
14
+ @subject = newsletter_name.humanize.titleize
15
+ @email = params[:email]
16
+ @newsletter_name = newsletter_name
17
+ mail_fields = {
18
+ subject: @subject,
19
+ to: params[:email]
20
+ }
21
+
22
+ premailer = Premailer.new(render("maktoub/newsletters/#{newsletter_name}").to_s,
23
+ with_html_string: true,
24
+ link_query_string: CGI::escape("utm_source=newsletter&utm_medium=email&utm_campaign=#{@subject}")
25
+ )
26
+
27
+ mail(mail_fields) do |format|
28
+ format.text { premailer.to_plain_text.html_safe }
29
+ format.html { premailer.to_inline_css.html_safe }
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,327 @@
1
+ /* Client-specific Styles */
2
+ #outlook a{padding:0;} /* Force Outlook to provide a "view in browser" button. */
3
+ body{width:100% !important;} .ReadMsgBody{width:100%;} .ExternalClass{width:100%;} /* Force Hotmail to display emails at full width */
4
+ body{-webkit-text-size-adjust:none;} /* Prevent Webkit platforms from changing default text sizes. */
5
+
6
+ /* Reset Styles */
7
+ body{margin:0; padding:0;}
8
+ img{border:0; height:auto; line-height:100%; outline:none; text-decoration:none;}
9
+ table td{border-collapse:collapse;}
10
+ #backgroundTable{height:100% !important; margin:0; padding:0; width:100% !important;}
11
+
12
+ /* Template Styles */
13
+
14
+ /* /\/\/\/\/\/\/\/\/\/\ STANDARD STYLING: COMMON PAGE ELEMENTS /\/\/\/\/\/\/\/\/\/\ */
15
+
16
+ /**
17
+ * @tab Page
18
+ * @section background color
19
+ * @tip Set the background color for your email. You may want to choose one that matches your company's branding.
20
+ * @theme page
21
+ */
22
+ body, #backgroundTable{
23
+ background-color:#FCFCFC;
24
+ }
25
+
26
+ hr {
27
+ margin-top: 0;
28
+ color: #CCCCCC;
29
+ }
30
+
31
+ /**
32
+ * @tab Page
33
+ * @section email border
34
+ * @tip Set the border for your email.
35
+ */
36
+ #templateContainer{
37
+
38
+ }
39
+
40
+ /**
41
+ * @tab Page
42
+ * @section heading 1
43
+ * @tip Set the styling for all first-level headings in your emails. These should be the largest of your headings.
44
+ * @style heading 1
45
+ */
46
+ h1, .h1{
47
+ color: #0099FF;
48
+ display:block;
49
+ font-family:Arial;
50
+ font-size:34px;
51
+ font-weight:bold;
52
+ line-height:100%;
53
+ margin-top:0;
54
+ margin-right:0;
55
+ margin-bottom:10px;
56
+ margin-left:0;
57
+ text-align:left;
58
+ }
59
+
60
+ /**
61
+ * @tab Page
62
+ * @section heading 2
63
+ * @tip Set the styling for all second-level headings in your emails.
64
+ * @style heading 2
65
+ */
66
+ h2, .h2{
67
+ color: #0099FF;
68
+ display:block;
69
+ font-family:Arial;
70
+ font-size:30px;
71
+ font-weight:bold;
72
+ line-height:100%;
73
+ margin-top:0;
74
+ margin-right:0;
75
+ margin-bottom:10px;
76
+ margin-left:0;
77
+ text-align:left;
78
+ }
79
+
80
+ /**
81
+ * @tab Page
82
+ * @section heading 3
83
+ * @tip Set the styling for all third-level headings in your emails.
84
+ * @style heading 3
85
+ */
86
+ h3, .h3{
87
+ color: #0099FF;
88
+ display:block;
89
+ font-family:Arial;
90
+ font-size:26px;
91
+ font-weight:bold;
92
+ line-height:100%;
93
+ margin-top:0;
94
+ margin-right:0;
95
+ margin-bottom:10px;
96
+ margin-left:0;
97
+ text-align:left;
98
+ }
99
+
100
+ /**
101
+ * @tab Page
102
+ * @section heading 4
103
+ * @tip Set the styling for all fourth-level headings in your emails. These should be the smallest of your headings.
104
+ * @style heading 4
105
+ */
106
+ h4, .h4{
107
+ color: #0099FF;
108
+ display:block;
109
+ font-family:Arial;
110
+ font-size:22px;
111
+ font-weight:bold;
112
+ line-height:100%;
113
+ margin-top:0;
114
+ margin-right:0;
115
+ margin-bottom:10px;
116
+ margin-left:0;
117
+ text-align:left;
118
+ }
119
+
120
+ /* /\/\/\/\/\/\/\/\/\/\ STANDARD STYLING: PREHEADER /\/\/\/\/\/\/\/\/\/\ */
121
+
122
+ /**
123
+ * @tab Header
124
+ * @section preheader style
125
+ * @tip Set the background color for your email's preheader area.
126
+ * @theme page
127
+ */
128
+ #templatePreheader{
129
+ background-color:#FCFCFC;
130
+ }
131
+
132
+ /**
133
+ * @tab Header
134
+ * @section preheader text
135
+ * @tip Set the styling for your email's preheader text. Choose a size and color that is easy to read.
136
+ */
137
+ .preheaderContent div{
138
+ color:#505050;
139
+ font-family:Arial;
140
+ font-size:10px;
141
+ line-height:100%;
142
+ text-align:left;
143
+ }
144
+
145
+ /**
146
+ * @tab Header
147
+ * @section preheader link
148
+ * @tip Set the styling for your email's preheader links. Choose a color that helps them stand out from your text.
149
+ */
150
+ .preheaderContent div a:link, .preheaderContent div a:visited, /* Yahoo! Mail Override */ .preheaderContent div a .yshortcuts /* Yahoo! Mail Override */{
151
+ color:#336699;
152
+ font-weight:normal;
153
+ text-decoration:underline;
154
+ }
155
+
156
+ /* /\/\/\/\/\/\/\/\/\/\ STANDARD STYLING: HEADER /\/\/\/\/\/\/\/\/\/\ */
157
+
158
+ /**
159
+ * @tab Header
160
+ * @section header style
161
+ * @tip Set the background color and border for your email's header area.
162
+ * @theme header
163
+ */
164
+ #templateHeader{
165
+ background-color:#FCFCFC;
166
+ border-bottom:0;
167
+ }
168
+
169
+ /**
170
+ * @tab Header
171
+ * @section header text
172
+ * @tip Set the styling for your email's header text. Choose a size and color that is easy to read.
173
+ */
174
+ .headerContent{
175
+ color:#202020;
176
+ font-family:Arial;
177
+ font-size:34px;
178
+ font-weight:bold;
179
+ line-height:100%;
180
+ padding:0;
181
+ text-align:left;
182
+ vertical-align:middle;
183
+ }
184
+
185
+ /**
186
+ * @tab Header
187
+ * @section header link
188
+ * @tip Set the styling for your email's header links. Choose a color that helps them stand out from your text.
189
+ */
190
+ .headerContent a:link, .headerContent a:visited, /* Yahoo! Mail Override */ .headerContent a .yshortcuts /* Yahoo! Mail Override */{
191
+ color:#336699;
192
+ font-weight:normal;
193
+ text-decoration:underline;
194
+ }
195
+
196
+ #headerImage{
197
+ height:auto;
198
+ max-width:600px !important;
199
+ }
200
+
201
+ /* /\/\/\/\/\/\/\/\/\/\ STANDARD STYLING: MAIN BODY /\/\/\/\/\/\/\/\/\/\ */
202
+
203
+ /**
204
+ * @tab Body
205
+ * @section body style
206
+ * @tip Set the background color for your email's body area.
207
+ */
208
+ #templateContainer, .bodyContent{
209
+ background-color:#FCFCFC;
210
+ }
211
+
212
+ /**
213
+ * @tab Body
214
+ * @section body text
215
+ * @tip Set the styling for your email's main content text. Choose a size and color that is easy to read.
216
+ * @theme main
217
+ */
218
+ .bodyContent div{
219
+ color:#505050;
220
+ font-family:Arial;
221
+ font-size:14px;
222
+ line-height:150%;
223
+ text-align:left;
224
+ }
225
+
226
+ /**
227
+ * @tab Body
228
+ * @section body link
229
+ * @tip Set the styling for your email's main content links. Choose a color that helps them stand out from your text.
230
+ */
231
+ .bodyContent div a:link, .bodyContent div a:visited, /* Yahoo! Mail Override */ .bodyContent div a .yshortcuts /* Yahoo! Mail Override */{
232
+ color:#336699;
233
+ font-weight:normal;
234
+ text-decoration:underline;
235
+ }
236
+
237
+ .bodyContent img{
238
+ display:inline;
239
+ height:auto;
240
+ }
241
+
242
+ /* /\/\/\/\/\/\/\/\/\/\ STANDARD STYLING: FOOTER /\/\/\/\/\/\/\/\/\/\ */
243
+
244
+ /**
245
+ * @tab Footer
246
+ * @section footer style
247
+ * @tip Set the background color and top border for your email's footer area.
248
+ * @theme footer
249
+ */
250
+ #templateFooter{
251
+ background-color:#FCFCFC;
252
+ border-top:0;
253
+ }
254
+
255
+ /**
256
+ * @tab Footer
257
+ * @section footer text
258
+ * @tip Set the styling for your email's footer text. Choose a size and color that is easy to read.
259
+ * @theme footer
260
+ */
261
+ .footerContent div{
262
+ color:#707070;
263
+ font-family:Arial;
264
+ font-size:12px;
265
+ line-height:125%;
266
+ text-align:left;
267
+ }
268
+
269
+ /**
270
+ * @tab Footer
271
+ * @section footer link
272
+ * @tip Set the styling for your email's footer links. Choose a color that helps them stand out from your text.
273
+ */
274
+ .footerContent div a:link, .footerContent div a:visited, /* Yahoo! Mail Override */ .footerContent div a .yshortcuts /* Yahoo! Mail Override */{
275
+ color:#336699;
276
+ font-weight:normal;
277
+ text-decoration:underline;
278
+ }
279
+
280
+ .footerContent img{
281
+ display:inline;
282
+ }
283
+
284
+ /**
285
+ * @tab Footer
286
+ * @section social bar style
287
+ * @tip Set the background color and border for your email's footer social bar.
288
+ * @theme footer
289
+ */
290
+ #social{
291
+ background-color:#FCFCFC;
292
+ border:0;
293
+ }
294
+
295
+ /**
296
+ * @tab Footer
297
+ * @section social bar style
298
+ * @tip Set the background color and border for your email's footer social bar.
299
+ */
300
+ #social div{
301
+ text-align:center;
302
+ }
303
+
304
+ /**
305
+ * @tab Footer
306
+ * @section utility bar style
307
+ * @tip Set the background color and border for your email's footer utility bar.
308
+ * @theme footer
309
+ */
310
+ #utility{
311
+ background-color:#FCFCFC;
312
+ border:0;
313
+ }
314
+
315
+ /**
316
+ * @tab Footer
317
+ * @section utility bar style
318
+ * @tip Set the background color and border for your email's footer utility bar.
319
+ */
320
+ #utility div{
321
+ text-align:center;
322
+ }
323
+
324
+ #monkeyRewards img{
325
+ max-width:190px;
326
+ }
327
+
@@ -0,0 +1,23 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Maktoub</title>
5
+ <%= stylesheet_link_tag "maktoub/application" %>
6
+ <%= javascript_include_tag "maktoub/application" %>
7
+ <%= csrf_meta_tags %>
8
+ <style type="text/css">
9
+ <%= render 'layouts/maktoub/styles' %>
10
+ div.container {
11
+ width: 600px;
12
+ margin: auto;
13
+ margin-top: 50px;
14
+ }
15
+ </style>
16
+ </head>
17
+ <body>
18
+ <div class="container">
19
+ <%= yield %>
20
+ </div>
21
+
22
+ </body>
23
+ </html>
@@ -0,0 +1,165 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5
+
6
+ <!-- Facebook sharing information tags -->
7
+ <meta property="og:title" content="<%= @subject %>" />
8
+ <meta name="viewport" content="width=680px, initial-scale=0.5">
9
+ <title><%= @subject %></title>
10
+ <style type="text/css">
11
+ <%= render 'layouts/maktoub/styles' %>
12
+ </style>
13
+ </head>
14
+ <body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0">
15
+ <center>
16
+ <table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="backgroundTable">
17
+ <tr>
18
+ <td align="center" valign="top">
19
+ <!-- // Begin Template Preheader \\ -->
20
+ <table border="0" cellpadding="10" cellspacing="0" width="600" id="templatePreheader">
21
+ <tr>
22
+ <td valign="top" class="preheaderContent">
23
+
24
+ <!-- // Begin Module: Standard Preheader \ -->
25
+ <table border="0" cellpadding="10" cellspacing="0" width="100%">
26
+ <tr>
27
+ <td valign="top">
28
+ <div>
29
+ <%= yield(:teaser) %>
30
+ </div>
31
+ </td>
32
+
33
+ <%- unless @archive %>
34
+ <td valign="top" width="190">
35
+ <div>
36
+ <%= @template %>
37
+ Is this email not displaying correctly?<br /><%= link_to "View it in your browser", newsletter_url(@newsletter_name), target: "_blank" %>.
38
+ </div>
39
+ </td>
40
+ <%- end %>
41
+ </tr>
42
+ </table>
43
+ <!-- // End Module: Standard Preheader \ -->
44
+
45
+ </td>
46
+ </tr>
47
+ </table>
48
+ <!-- // End Template Preheader \\ -->
49
+ <table border="0" cellpadding="0" cellspacing="0" width="600" id="templateContainer">
50
+ <tr>
51
+ <td align="center" valign="top">
52
+ <!-- // Begin Template Header \\ -->
53
+ <table border="0" cellpadding="0" cellspacing="0" width="600" id="templateHeader">
54
+ <tr>
55
+ <td class="headerContent">
56
+
57
+ <!-- // Begin Module: Standard Header Image \\ -->
58
+ <% img = image_tag Maktoub.logo, :style => "max-width:600px", :id => "headerImage campaign-icon", :alt => Maktoub.app_name %>
59
+ <%= link_to img, Maktoub.home_url, :target => "_blank" %>
60
+ <!-- // End Module: Standard Header Image \\ -->
61
+ <hr />
62
+ </td>
63
+ </tr>
64
+ </table>
65
+ <!-- // End Template Header \\ -->
66
+ </td>
67
+ </tr>
68
+ <tr>
69
+ <td align="center" valign="top">
70
+ <!-- // Begin Template Body \\ -->
71
+ <table border="0" cellpadding="0" cellspacing="0" width="600" id="templateBody">
72
+ <tr>
73
+ <td valign="top" class="bodyContent">
74
+
75
+ <!-- // Begin Module: Standard Content \\ -->
76
+ <table border="0" cellpadding="20" cellspacing="0" width="100%">
77
+ <tr>
78
+ <td valign="top">
79
+ <div mc:edit="std_content00">
80
+ <%= yield %>
81
+ </div>
82
+ </td>
83
+ </tr>
84
+ </table>
85
+ <!-- // End Module: Standard Content \\ -->
86
+
87
+ </td>
88
+ </tr>
89
+ </table>
90
+ <!-- // End Template Body \\ -->
91
+ </td>
92
+ </tr>
93
+ <tr>
94
+ <td align="center" valign="top">
95
+ <!-- // Begin Template Footer \\ -->
96
+ <table border="0" cellpadding="10" cellspacing="0" width="600" id="templateFooter">
97
+ <tr>
98
+ <td valign="top" class="footerContent">
99
+
100
+ <!-- // Begin Module: Standard Footer \\ -->
101
+ <table border="0" cellpadding="10" cellspacing="0" width="100%">
102
+ <tr>
103
+ <td colspan="2" valign="middle" id="social">
104
+ <div mc:edit="std_social">
105
+ &nbsp;
106
+ <% unless Maktoub.twitter_url.blank? %>
107
+ <%= link_to 'follow on Twitter', Maktoub.twitter_url, :target => "_blank" %>
108
+ <% end %>
109
+ <% unless Maktoub.facebook_url.blank? %>
110
+ |
111
+ <%= link_to 'friend on Facebook', Maktoub.facebook_url, :target => "_blank" %>
112
+ <% end %>
113
+ <% unless Maktoub.google_plus_url.blank? %>
114
+ |
115
+ <%= link_to 'follow on Google+', Maktoub.google_plus_url, :target => "_blank" %>
116
+ <% end %>
117
+ &nbsp;
118
+ </div>
119
+ </td>
120
+ </tr>
121
+ <tr>
122
+ <td valign="top" width="350">
123
+ <div mc:edit="std_footer">
124
+ <em>Copyright &copy; <%= Time.now.year %> <%= Maktoub.app_name %>, All rights reserved.</em>
125
+ <br />
126
+ <em>You are receiving this email because you opted in at our website <%= link_to Maktoub.home_url, Maktoub.home_url, :target => "_blank" %>.</em>
127
+ <br />
128
+ <%- unless @archive %>
129
+ <%# we are not including mailing addresses %>
130
+ <%#<br /><strong>Our mailing address is:</strong><br /> %>
131
+ <%# %>
132
+ <%- end %>
133
+ </div>
134
+ </td>
135
+
136
+ </tr>
137
+ <tr>
138
+ <td colspan="2" valign="middle" id="utility">
139
+ <div>
140
+ &nbsp;<%= link_to 'update subscription preferences', Maktoub.subscription_preferences_url, :target => "_blank" %>&nbsp;
141
+ <%- if Maktoub.unsubscribe_method %>
142
+ | <%= link_to 'unsubscribe', edit_subscribers_url, :target => "_blank", :rel => "nofollow" %>
143
+
144
+ <% end %>
145
+ </div>
146
+ </td>
147
+ </tr>
148
+ </table>
149
+ <!-- // End Module: Standard Footer \\ -->
150
+
151
+ </td>
152
+ </tr>
153
+ </table>
154
+ <!-- // End Template Footer \\ -->
155
+ </td>
156
+ </tr>
157
+ </table>
158
+ <br />
159
+ </td>
160
+ </tr>
161
+ </table>
162
+ </center>
163
+ </body>
164
+ </html>
165
+
@@ -0,0 +1,3 @@
1
+ <h1>Readme</h1>
2
+ <p>Place your newsletter partials in your views/maktoub/newsletters folder. The partial name is converted into the newsletter subject.</p>
3
+
@@ -0,0 +1,16 @@
1
+ <h1>Unsubscribe from newsletter</h1>
2
+
3
+ <%= form_tag subscribers_path, :method => :put do |f| %>
4
+ <p>
5
+ <%= label :subscribers, 'Email', :for => 'email' %>
6
+ <br/>
7
+ <%- if @message %>
8
+ <div style="color:red;"><%= @message %></div>
9
+ <%- end %>
10
+ <%= text_field :subscribers, 'email', {:type => "email", :id => 'email', :name => 'email'} %>
11
+ <br />
12
+ </p>
13
+ <p>
14
+ <%= button_tag 'submit', :type => 'submit' %>
15
+ </o>
16
+ <% end %>
@@ -0,0 +1 @@
1
+ <h1>Unsubscribe successful</h1>
@@ -0,0 +1,10 @@
1
+ Maktoub::Engine.routes.draw do
2
+
3
+ get "newsletter/(:newsletter)" => "archives#show", as: "newsletter"
4
+
5
+ root to: "archives#show"
6
+
7
+ resource :subscribers, :only => [:edit, :update]
8
+
9
+ end
10
+
@@ -0,0 +1,3 @@
1
+ Description:
2
+ The maktoub:install generator creates a configuration file in config/initializer
3
+ directory.
@@ -0,0 +1,11 @@
1
+ module Maktoub
2
+ module Generators
3
+ class ConfigGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ def generate_maktoub
7
+ copy_file "maktoub.rb", "config/initializers/maktoub.rb"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ # Maktoub.from = "Test Sender <maktoub@example.com>" # the email the newsletter is sent from
2
+ # Maktoub.twitter_url = "http://twitter.com/#!/twitter" # your twitter page
3
+ # Maktoub.facebook_url = "http://www.facebook.com/facebook" # your facebook oage
4
+ # Maktoub.subscription_preferences_url = "http://example.com/manage_subscriptions" #subscribers management url
5
+ # Maktoub.logo = "logo.jpg" # path to your logo asset
6
+ # Maktoub.home_domain = "example.com" # your domain
7
+ # Maktoub.app_name = "Maktoub" # your app name
8
+ # Maktoub.unsubscribe_method = "unsubscribe" # method to call from unsubscribe link (doesn't include link by default)
9
+
10
+ # pass a block to subscribers_extractor that returns an object that reponds to :name and :email
11
+ # (fields can be configured as shown below)
12
+
13
+ # require "ostruct"
14
+ # Maktoub.subscribers_extractor do
15
+ # (1..5).map do |i|
16
+ # users << OpenStruct.new({name: "tester#{i}", email: "test#{i}@example.com"})
17
+ # end
18
+ # end
19
+
20
+ # uncomment lines below to change subscriber fields that contain email and
21
+ # Maktoub.email_field = :address
22
+ # Maktoub.name_field = :nickname
@@ -0,0 +1,46 @@
1
+ require "maktoub/engine"
2
+
3
+ module Maktoub
4
+ class << self
5
+ attr_accessor :from,
6
+ :twitter_url,
7
+ :facebook_url,
8
+ :google_plus_url,
9
+ :subscription_preferences_url,
10
+ :logo,
11
+ :home_domain,
12
+ :app_name,
13
+ :unsubscribe_method
14
+
15
+ attr_writer :email_field, :name_field
16
+
17
+ def email_field
18
+ @email_field || :email
19
+ end
20
+
21
+ def name_field
22
+ @name_field || :name
23
+ end
24
+
25
+ def subscribers
26
+ @subscribers.call
27
+ end
28
+
29
+ def subscribers_extractor (&block)
30
+ @subscribers = Proc.new &block
31
+ end
32
+
33
+ def unsubscribe(email)
34
+ subscribers.select do |s|
35
+ s.send(email_field) == email
36
+ end.each do |s|
37
+ s.send(unsubscribe_method) if unsubscribe_method
38
+ end
39
+ end
40
+
41
+ def home_url
42
+ "http://" + home_domain
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,6 @@
1
+ module Maktoub
2
+ class Engine < Rails::Engine
3
+ isolate_namespace Maktoub
4
+ end
5
+ end
6
+
@@ -0,0 +1,4 @@
1
+ module Maktoub
2
+ VERSION = "0.2.5"
3
+ end
4
+
@@ -0,0 +1,29 @@
1
+ namespace :maktoub do
2
+ desc "send :newsletter to the configured from address"
3
+ task :test, [:newsletter] => [:environment] do |t, args|
4
+ if Maktoub::NewsletterMailer.method_defined? :delay
5
+ Maktoub::NewsletterMailer.delay(:priority => 5, :queue => 'maktoub').publish(args[:newsletter], :email => Maktoub.from, :name => 'Tester')
6
+ puts "delayed #{Maktoub.from}"
7
+ else
8
+ Maktoub::NewsletterMailer.publish(args[:newsletter], :email => Maktoub.from, :name => 'Joe Tester').deliver
9
+ puts "delivered #{Maktoub.from}"
10
+ end
11
+ end
12
+
13
+ desc "send :newsletter to all subscribers"
14
+ task :mail, [:newsletter] => [:environment] do |t, args|
15
+ puts "starting..."
16
+ messages = Maktoub.subscribers.map do |u|
17
+ if Maktoub::NewsletterMailer.method_defined? :delay
18
+ Maktoub::NewsletterMailer.delay(:priority => 5, :queue => 'maktoub').publish(args[:newsletter], :email => u.send(Maktoub.email_field), :name => u.send(Maktoub.name_field))
19
+ "delayed #{u.send Maktoub.email_field}"
20
+ else
21
+ Maktoub::NewsletterMailer.publish(args[:newsletter], :email => u.send(Maktoub.email_field), :name => u.send(Maktoub.name_field)).deliver
22
+ "delivered #{u.send Maktoub.email_field}"
23
+ end
24
+ end
25
+ puts "#{messages.length} messages"
26
+ puts messages.join("\n")
27
+ end
28
+ end
29
+
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resque-maktoub
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Zaid Zawaideh
9
+ - Rodi Alessandro
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-01-23 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rails
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 3.1.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: 3.1.1
31
+ - !ruby/object:Gem::Dependency
32
+ name: premailer
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: nokogiri
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: resque_mailer
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ - !ruby/object:Gem::Dependency
80
+ name: sqlite3
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rspec-rails
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: A simple asynchronousnewsletter engine for rails powered by resque.
112
+ email:
113
+ - coorasse@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - app/controllers/maktoub/archives_controller.rb
119
+ - app/controllers/maktoub/subscribers_controller.rb
120
+ - app/controllers/maktoub/application_controller.rb
121
+ - app/assets/stylesheets/maktoub/application.css
122
+ - app/assets/stylesheets/maktoub/archives.css
123
+ - app/assets/javascripts/maktoub/archives.js
124
+ - app/assets/javascripts/maktoub/application.js
125
+ - app/mailers/maktoub/newsletter_mailer.rb
126
+ - app/helpers/maktoub/application_helper.rb
127
+ - app/helpers/maktoub/archives_helper.rb
128
+ - app/views/layouts/maktoub/application.html.erb
129
+ - app/views/layouts/maktoub/_styles.erb
130
+ - app/views/layouts/maktoub/newsletter_mailer.erb
131
+ - app/views/maktoub/newsletters/readme.erb
132
+ - app/views/maktoub/subscribers/edit.html.erb
133
+ - app/views/maktoub/subscribers/update.html.erb
134
+ - config/routes.rb
135
+ - lib/tasks/maktoub_tasks.rake
136
+ - lib/generators/maktoub/USAGE
137
+ - lib/generators/maktoub/templates/maktoub.rb
138
+ - lib/generators/maktoub/config_generator.rb
139
+ - lib/maktoub/version.rb
140
+ - lib/maktoub/engine.rb
141
+ - lib/maktoub.rb
142
+ - MIT-LICENSE
143
+ - Rakefile
144
+ - README.rdoc
145
+ homepage: http://www.rodialessandro.id
146
+ licenses: []
147
+ post_install_message:
148
+ rdoc_options: []
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ! '>='
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ none: false
159
+ requirements:
160
+ - - ! '>='
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ requirements: []
164
+ rubyforge_project:
165
+ rubygems_version: 1.8.24
166
+ signing_key:
167
+ specification_version: 3
168
+ summary: A simple asynchronous newsletter engine for rails powered by resque.
169
+ test_files: []