Skip to content
Browse files

Added SMTP support

git-svn-id: file:///svn/gracelist@5 d7bf5ae1-4f24-0410-b5c4-8995abff36bd
  • Loading branch information...
1 parent 45acd91 commit 182adbc3d7beea28a713bd7beba8a3fbdd1db92e conrad committed Dec 14, 2006
View
18 app/controllers/posts_controller.rb
@@ -60,4 +60,22 @@ def destroy
# About GraceList
def about
end
+
+ # Convenience action to preview the newsletter
+ def newsletter
+ index
+ render :layout => false
+ end
+
+ # Send out newsletter
+ def notify
+ # Render the newsletter
+ @categories = Category.find_all
+ body = render_to_string :action => 'newsletter', :layout => 'mail'
+
+ # Deliver the newsletter
+ Notifier.deliver_newsletter(body, Post.recent_items.to_s)
+ flash[:notice] = 'Newsletter has been sent.'
+ redirect_to :action => 'index'
+ end
end
View
10 app/helpers/posts_helper.rb
@@ -2,4 +2,14 @@ module PostsHelper
def required
'<span class="required">*</span>'
end
+
+ # Return as new item if date is more than 2 days old
+ # Arg: d is a Date object
+ # Arg: inline_styled is a Boolean for using inline CSS styles
+ def mark_as_new(d, inline_styled = false)
+ if d > NOTIFY_FREQUENCY.days.ago
+ return '<span style="font-size: 10px; color: #ffffff; background-color: #cc0000; padding: 1px 3px 1px 3px; margin: 0 0 0 4px;">new</span>' if inline_styled
+ return '<span class="new">new</span>'
+ end
+ end
end
View
12 app/models/notifier.rb
@@ -0,0 +1,12 @@
+class Notifier < ActionMailer::Base
+
+ def newsletter(body, recent_items, sent_at = Time.now)
+ @subject = '[GraceList] ' + sent_at.strftime('%A, %m/%d') + ' - ' + recent_items + ' new posts'
+ @body = {"body" => body}
+ @recipients = 'conradchu@conradchu.com'
+ @from = 'gracelist@gpmail.org'
+ @sent_on = sent_at
+ @headers = {}
+ @content_type = "text/html"
+ end
+end
View
12 app/models/post.rb
@@ -2,4 +2,16 @@ class Post < ActiveRecord::Base
belongs_to :category
validates_presence_of :title, :description, :category_id, :author, :email
+
+ def Post.recent_items
+ num_recent = 0
+
+ posts = Post.find_all
+ posts.each do |p|
+ num_recent += 1 if p.created_at > NOTIFY_FREQUENCY.days.ago
+ end
+
+ num_recent
+ end
+
end
View
3 app/views/layouts/application.rhtml
@@ -14,6 +14,9 @@
<%= link_to 'Home', { :controller => 'posts', :action => 'index' } %> |
<%= link_to 'About GraceList', { :controller => 'posts', :action => 'about' } %> |
<a href="http://www.gracepointonline.org/gracewiki">Back to GraceWiki</a>
+ <% if Post.recent_items > 0 %>
+ <div class="emailUpdate">Next email will be sent on <%= (Date.today + NOTIFY_FREQUENCY).strftime('%A, %b %d, %I:%M%p') %></div>
+ <% end %>
</div>
<div class="title">
<h1>GraceList</h1>
View
1 app/views/layouts/mail.rhtml
@@ -0,0 +1 @@
+<%= @content_for_layout %>
View
1 app/views/notifier/newsletter.rhtml
@@ -0,0 +1 @@
+<%= @body %>
View
10 app/views/posts/index.rhtml
@@ -3,9 +3,9 @@
<% @categories.each do |c| %>
<% if c.name != 'Announcements' %>
<h2><%=h c.name %></h2>
- <% Post.find_all_by_category_id(c.id, :limit => 10).each do |p| %>
+ <% Post.find_all_by_category_id(c.id, :limit => 10, :order => 'created_at DESC').each do |p| %>
<div class="post clearfix">
- <div class="title"><%= link_to p.title, :action => 'show', :id => p.id %></div>
+ <div class="title"><%= link_to p.title, :action => 'show', :id => p.id %><%= mark_as_new(p.created_at) %></div>
<div class="date"><%= p.created_at.strftime('%a, %b %d') %></div>
</div>
<% end %>
@@ -22,15 +22,15 @@
<h2>Announcements</h2>
<% @categories.each do |c| %>
<% if c.name == 'Announcements' %>
- <% Post.find_all_by_category_id(c.id, :limit => 10).each do |p| %>
+ <% Post.find_all_by_category_id(c.id, :limit => 10, :order => 'created_at DESC').each do |p| %>
<div class="announcement clearfix">
- <div class="title"><%=h p.title %></div>
+ <div class="title"><%=h p.title %><%= mark_as_new(p.created_at) %></div>
<div class="author">Posted by <%= mail_to p.email, p.author %> on <%= p.created_at.strftime('%a, %b %d') %></div>
<div class="excerpt"><%=h truncate p.description, 150 %> <%= link_to '(more)', :action => 'show', :id => p.id %></div>
</div>
<% end %>
<div class="buttons">
- <%= link_to 'Add an Announcement', :action => 'new', :category_id => c.id %> |
+ <%= link_to 'Make an Announcement', :action => 'new', :category_id => c.id %> |
<%= link_to 'View All', :action => 'list', :category_id => c.id %>
</div>
<% end %>
View
4 app/views/posts/new.rhtml
@@ -6,6 +6,4 @@
<div class="buttons">
<%= submit_tag 'Add Post', :tabindex => '6' %> or <%= link_to 'Cancel', :action => 'index' %>
</div>
-<% end %>
-
-
+<% end %>
View
79 app/views/posts/newsletter.rhtml
@@ -0,0 +1,79 @@
+<table cellspacing="0" cellpadding="0" border="0" width="650px" align="center">
+ <tr>
+ <td colspan="3" style="font-family: 'Lucida Grande', Arial, sans-serif; font-size: 11px; color: #fff; text-align: center; padding: 5px; background-color: #000">Having trouble reading this email? - <%= link_to 'View the web version instead', { :action => 'index', :only_path => false }, :style => 'color: #0e85ff'%></td>
+ </tr>
+ <tr>
+ <td colspan="3">
+ <table cellspacing="0" cellpadding="0" border="0" width="100%">
+ <tr>
+ <td style="font-family: 'Lucida Grande', Arial, sans-serif; color: #ffffff; padding: 4px 16px; background-color: #006297; margin: 1px 0 0 0">
+ <h1 style="font-size: 32px; margin: 0;">GraceList</h1>
+ <h2 style="font-weight: normal; font-size: 12px; margin: 0 0 6px 3px;">Community Bulletin Board</h2>
+ </td>
+ <td style="font-family: 'Lucida Grande', Arial, sans-serif; color: #ffffff; padding: 4px 16px; background-color: #006297; margin: 1px 0 0 0">
+ <div style="font-size: 16px; text-align: right; padding: 0 6px 0 0"><%= Date.today.strftime('%A, %b %d') %></div>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <td style="background-color: #eeeeee;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td width="100%" style="background-color: #ffffff; vertical-align: top; padding: 16px;">
+ <table cellspacing="0" cellpadding="0" border="0" width="100%">
+ <tr>
+ <td width="55%" style="vertical-align: top;">
+ <% @categories.each do |c| %>
+ <% if c.name != 'Announcements' %>
+ <h2 style="font-family: 'Lucida Grande', Arial, sans-serif; font-size: 20px; color: #333333; margin: 0 0 6px 0; border-top: 1px solid #eeeeee; padding: 14px 0 0 0;"><%=h c.name %></h2>
+ <% Post.find_all_by_category_id(c.id, :limit => 6, :order => 'created_at DESC').each do |p| %>
+ <table cellspacing="0" cellpadding="0" border="0" width="100%">
+ <tr>
+ <td width="75%" style="font-family: 'Lucida Grande', Arial, sans-serif; font-size: 13px; padding: 3px 0 3px 0"><%= link_to p.title, { :action => 'show', :id => p.id, :only_path => false }, :style => 'color: #0e85ff' %><%= mark_as_new(p.created_at, 't') %></td>
+ <td width="25%" style="font-family: 'Lucida Grande', Arial, sans-serif; font-size: 12px; color: #555555; padding: 3px 0 3px 0"><%= p.created_at.strftime('%a, %b %d') %></td>
+ </tr>
+ </table>
+ <% end %>
+ <div style="font-family: 'Lucida Grande', Arial, sans-serif; margin: 14px 0 22px 0; font-size: 12px">
+ <%= link_to 'New Post', { :action => 'new', :category_id => c.id, :only_path => false }, :style => 'color: #0e85ff' %> |
+ <%= link_to 'View All', { :action => 'list', :category_id => c.id, :only_path => false }, :style => 'color: #0e85ff' %>
+ </div>
+ <% end %>
+ <% end %>
+ </td>
+ <td width="45%" style="vertical-align: top; padding: 0 0 0 32px">
+ <div style="border: 2px solid #FEE19F; background-color: #FDF9EE; padding: 12px;">
+ <h2 style="font-family: 'Lucida Grande', Arial, sans-serif; color: #333333; font-size: 20px; margin: 12px 0 16px 0;">Announcements</h2>
+ <table cellspacing="0" cellpadding="0" border="0" width="100%">
+ <% @categories.each do |c| %>
+ <% if c.name == 'Announcements' %>
+ <% Post.find_all_by_category_id(c.id, :limit => 5, :order => 'created_at DESC').each do |p| %>
+ <tr>
+ <td>
+ <h3 style="font-family: 'Lucida Grande', Arial, sans-serif; font-size: 14px; font-weight: bold; color: #333333; margin: 0;"><%=h p.title %><%= mark_as_new(p.created_at, 't') %></h3>
+ <div style="font-family: 'Lucida Grande', Arial, sans-serif; color: #333333; font-size: 11px; margin: 2px 0 2px 0">Posted by <%= mail_to p.email, p.author, :style => 'color: #0e85ff' %> on <%= p.created_at.strftime('%a, %b %d') %></div>
+ <div style="font-family: 'Lucida Grande', Arial, sans-serif; color: #333333; font-size: 12px; margin: 0 0 20px 0; line-height: 18px"><%=h truncate p.description, 150 %> <%= link_to '(more)', { :action => 'show', :id => p.id, :only_path => false }, :style => 'color: #0e85ff' %></div>
+ </td>
+ </tr>
+ <% end %>
+ <tr>
+ <td colspan="2">
+ <div style="font-family: 'Lucida Grande', Arial, sans-serif; margin: 14px 0 22px 0; font-size: 12px">
+ <%= link_to 'Make an Announcement', { :action => 'new', :category_id => c.id, :only_path => false }, :style => 'color: #0e85ff' %> |
+ <%= link_to 'View All', { :action => 'list', :category_id => c.id, :only_path => false }, :style => 'color: #0e85ff' %>
+ </div>
+ </td>
+ </tr>
+ <% end %>
+ <% end %>
+ </table>
+ </div>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td style="background-color: #eeeeee;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
+</tr>
+<tr>
+ <td colspan="3" style="font-family: 'Lucida Grande', Arial, sans-serif; color: #333333; font-size: 11px; background-color: #eeeeee; text-align: center; padding: 5px 0 5px 0">Submit bugs to <a style="color: #0e85ff" href="http://trac.gracepointonline.org/">GraceTrac</a></td>
+</tr>
+</table>
View
18 config/config.yml
@@ -0,0 +1,18 @@
+development:
+ email:
+ server: mail.berkmedia.org
+ port: 25
+ domain: www.berkmedia.org
+ authentication: login
+ username: gracelist+berkmedia.org
+ password: gracelistrules
+ contact_recipient: gracelist@berkmedia.org
+production:
+ email:
+ server: localhost
+ port: 25
+ domain: www.gracepointonline.org
+ authentication: login
+ username:
+ password:
+ contact_recipient: josh@IRealyDontWantSpam.com
View
17 config/environment.rb
@@ -50,4 +50,19 @@
# inflect.uncountable %w( fish sheep )
# end
-# Include your application configuration below
+# Include your application configuration below
+
+# Frequency of notifications
+NOTIFY_FREQUENCY = 2
+
+c = YAML::load(File.open("#{RAILS_ROOT}/config/config.yml"))
+ActionMailer::Base.raise_delivery_errors = true
+ActionMailer::Base.delivery_method = :smtp
+ActionMailer::Base.server_settings = {
+ :address => c[RAILS_ENV]['email']['server'],
+ :port => c[RAILS_ENV]['email']['port'],
+ :domain => c[RAILS_ENV]['email']['domain'],
+ :authentication => c[RAILS_ENV]['email']['authentication'],
+ :user_name => c[RAILS_ENV]['email']['username'],
+ :password => c[RAILS_ENV]['email']['password']
+}
View
2 log/locomotive.pid
@@ -1 +1 @@
-2566
+3659
View
BIN public/images/gracelist.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
27 public/stylesheets/styles.css
@@ -29,11 +29,6 @@ label {
font-weight: bold;
}
-.big {
- font-size: 15px;
- line-height: 1.5em;
-}
-
/* HEADER
--------------------------------------------------------------------*/
@@ -139,11 +134,9 @@ tr.highlight {
background-color: #FFF;
}
-.tagToolbox {
- padding: 6px;
- margin: 3px 0 0 0;
- background-color: #fffff3;
- border: 1px solid #ffecb1;
+.emailUpdate {
+ font-size: 11px;
+ margin: 4px 0 0 0;
}
/* OTHER CLASSES
@@ -192,6 +185,19 @@ tr.highlight {
font-size: 11px;
}
+.big {
+ font-size: 15px;
+ line-height: 1.5em;
+}
+
+.new {
+ font-size: 10px;
+ color: #fff;
+ background-color: #c00;
+ padding: 1px 3px;
+ margin: 0 0 0 4px;
+}
+
.optional {
color: #AAA;
font-size: 11px;
@@ -245,6 +251,7 @@ tr.highlight {
.post .date {
color: #555;
font-size: 11px;
+ margin: 0 0 0 10px;
width: 75px;
}
View
3 test/fixtures/notifier/newsletter
@@ -0,0 +1,3 @@
+Notifier#newsletter
+
+Find me in app/views/notifier/newsletter.rhtml
View
35 test/unit/notifier_test.rb
@@ -0,0 +1,35 @@
+require File.dirname(__FILE__) + '/../test_helper'
+require 'notifier'
+
+class NotifierTest < Test::Unit::TestCase
+ FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures'
+ CHARSET = "utf-8"
+
+ include ActionMailer::Quoting
+
+ def setup
+ ActionMailer::Base.delivery_method = :test
+ ActionMailer::Base.perform_deliveries = true
+ ActionMailer::Base.deliveries = []
+
+ @expected = TMail::Mail.new
+ @expected.set_content_type "text", "plain", { "charset" => CHARSET }
+ end
+
+ def test_newsletter
+ @expected.subject = 'Notifier#newsletter'
+ @expected.body = read_fixture('newsletter')
+ @expected.date = Time.now
+
+ assert_equal @expected.encoded, Notifier.create_newsletter(@expected.date).encoded
+ end
+
+ private
+ def read_fixture(action)
+ IO.readlines("#{FIXTURES_PATH}/notifier/#{action}")
+ end
+
+ def encode(subject)
+ quoted_printable(subject, CHARSET)
+ end
+end

0 comments on commit 182adbc

Please sign in to comment.
Something went wrong with that request. Please try again.