email and pushover reply notifications

This commit is contained in:
joshua stein 2012-07-03 11:59:50 -05:00
parent da48f74e45
commit d9b95b2a1d
15 changed files with 100 additions and 27 deletions

View file

@ -540,6 +540,10 @@ div#story_box div.markdown_help_toggler {
width: 610px; width: 610px;
} }
div.comment_form_container {
max-width: 550px;
}
/* data tables */ /* data tables */
table.data caption { table.data caption {

View file

@ -7,7 +7,7 @@ class InvitationsController < ApplicationController
i.email = params[:email] i.email = params[:email]
i.memo = params[:memo] i.memo = params[:memo]
if i.save if i.save
i.send_email(root_url) i.send_email
flash[:success] = "Successfully e-mailed invitation to " << flash[:success] = "Successfully e-mailed invitation to " <<
params[:email] params[:email]
else else

View file

@ -39,7 +39,7 @@ class LoginController < ApplicationController
return forgot_password return forgot_password
end end
@found_user.initiate_password_reset_for_ip(root_url, request.remote_ip) @found_user.initiate_password_reset_for_ip(request.remote_ip)
flash.now[:success] = "Password reset instructions have been e-mailed " << flash.now[:success] = "Password reset instructions have been e-mailed " <<
"to you." "to you."

View file

@ -0,0 +1,12 @@
class EmailReply < ActionMailer::Base
default :from => "nobody@lobste.rs"
def reply(comment, user)
@comment = comment
@user = user
mail(:to => user.email, :from => "Lobsters <nobody@lobste.rs>",
:subject => "[Lobsters] Reply from #{comment.user.username} on " <<
"#{comment.story.title}")
end
end

View file

@ -1,11 +1,9 @@
class InvitationMailer < ActionMailer::Base class InvitationMailer < ActionMailer::Base
default from: "nobody@lobste.rs" def invitation(invitation)
def invitation(root_url, invitation)
@root_url = root_url
@invitation = invitation @invitation = invitation
mail(to: invitation.email, from: "Lobsters Invitation <nobody@lobste.rs>", mail(:to => invitation.email,
:from => "Lobsters Invitation <nobody@lobste.rs>",
subject: "[Lobsters] Welcome to Lobsters") subject: "[Lobsters] Welcome to Lobsters")
end end
end end

View file

@ -1,12 +1,9 @@
class PasswordReset < ActionMailer::Base class PasswordReset < ActionMailer::Base
default from: "nobody@lobste.rs" def password_reset_link(user, ip)
def password_reset_link(root_url, user, ip)
@root_url = root_url
@user = user @user = user
@ip = ip @ip = ip
mail(to: user.email, from: "Lobsters <nobody@lobste.rs>", mail(:to => user.email, :from => "Lobsters <nobody@lobste.rs>",
subject: "[Lobsters] Reset your password") :subject => "[Lobsters] Reset your password")
end end
end end

View file

@ -3,6 +3,8 @@ class Comment < ActiveRecord::Base
belongs_to :story belongs_to :story
has_many :votes, has_many :votes,
:dependent => :delete_all :dependent => :delete_all
belongs_to :parent_comment,
:class_name => "Comment"
attr_accessible :comment attr_accessible :comment
@ -10,7 +12,7 @@ class Comment < ActiveRecord::Base
:indent_level :indent_level
before_create :assign_short_id_and_upvote before_create :assign_short_id_and_upvote
after_create :assign_votes, :mark_submitter after_create :assign_votes, :mark_submitter, :email_reply
after_destroy :unassign_votes after_destroy :unassign_votes
MAX_EDIT_MINS = 45 MAX_EDIT_MINS = 45
@ -54,6 +56,27 @@ class Comment < ActiveRecord::Base
Keystore.increment_value_for("user:#{self.user_id}:comments_posted") Keystore.increment_value_for("user:#{self.user_id}:comments_posted")
end end
def email_reply
begin
if self.parent_comment_id && u = self.parent_comment.try(:user)
if u.email_replies?
EmailReply.reply(self, u).deliver
end
if u.pushover_replies?
Pushover.push(u.pushover_user_key, u.pushover_device, {
:title => "Lobsters reply from #{self.user.username} on " <<
"#{self.story.title}",
:message => self.plaintext_comment,
:url => self.url,
:url_title => "Reply to #{self.user.username}",
})
end
end
rescue
end
end
# http://evanmiller.org/how-not-to-sort-by-average-rating.html # http://evanmiller.org/how-not-to-sort-by-average-rating.html
# https://github.com/reddit/reddit/blob/master/r2/r2/lib/db/_sorts.pyx # https://github.com/reddit/reddit/blob/master/r2/r2/lib/db/_sorts.pyx
def confidence def confidence
@ -85,6 +108,11 @@ class Comment < ActiveRecord::Base
:filter_html).to_html :filter_html).to_html
end end
def plaintext_comment
# TODO: linkify then strip tags and convert entities back
comment
end
def flag! def flag!
Story.update_counters self.id, :flaggings => 1 Story.update_counters self.id, :flaggings => 1
end end
@ -132,4 +160,8 @@ class Comment < ActiveRecord::Base
(Time.now.to_i - self.created_at.to_i < (60 * MAX_EDIT_MINS)) (Time.now.to_i - self.created_at.to_i < (60 * MAX_EDIT_MINS))
end end
def url
self.story.comments_url + "/comments/#{self.short_id}"
end
end end

View file

@ -21,7 +21,7 @@ class Invitation < ActiveRecord::Base
end end
end end
def send_email(root_url) def send_email
InvitationMailer.invitation(root_url, self).deliver InvitationMailer.invitation(self).deliver
end end
end end

View file

@ -84,12 +84,12 @@ class Story < ActiveRecord::Base
self.tags_to_add = [] self.tags_to_add = []
end end
def comments_url(root_url = "/") def comments_url
"#{short_id_url(root_url)}/#{self.title_as_url}" "#{short_id_url}/#{self.title_as_url}"
end end
def short_id_url(root_url = "/") def short_id_url
root_url + "s/#{self.short_id}" Rails.application.routes.url_helpers.root_url + "s/#{self.short_id}"
end end
@_comment_count = nil @_comment_count = nil
@ -187,8 +187,8 @@ class Story < ActiveRecord::Base
u.gsub(/^_+/, "").gsub(/_+$/, "") u.gsub(/^_+/, "").gsub(/_+$/, "")
end end
def url_or_comments_url(root_url = "/") def url_or_comments_url
self.url.blank? ? self.comments_url(root_url) : self.url self.url.blank? ? self.comments_url : self.url
end end
def is_editable_by_user?(user) def is_editable_by_user?(user)

View file

@ -40,11 +40,11 @@ class User < ActiveRecord::Base
Keystore.value_for("user:#{self.id}:comments_posted").to_i Keystore.value_for("user:#{self.id}:comments_posted").to_i
end end
def initiate_password_reset_for_ip(root_url, ip) def initiate_password_reset_for_ip(ip)
self.password_reset_token = Utils.random_str(40) self.password_reset_token = Utils.random_str(40)
self.save! self.save!
PasswordReset.password_reset_link(root_url, self, ip).deliver PasswordReset.password_reset_link(self, ip).deliver
end end
def linkified_about def linkified_about

View file

@ -1,4 +1,4 @@
<div class="form_container"> <div class="comment_form_container">
<%= form_tag("/comments/#{story.short_id}", { :id => "comment_form" }) do |f| %> <%= form_tag("/comments/#{story.short_id}", { :id => "comment_form" }) do |f| %>
<% if comment.parent_comment_short_id.present? %> <% if comment.parent_comment_short_id.present? %>
<%= hidden_field_tag "parent_comment_short_id", <%= hidden_field_tag "parent_comment_short_id",

View file

@ -0,0 +1,7 @@
<%= @comment.user.username %> has replied to you:
<%= word_wrap(@comment.plaintext_comment, :line_width => 72).gsub(/\n/, "\n ") %>
You can view this reply at:
<%= @comment.url %>

View file

@ -4,4 +4,4 @@ The user <%= @invitation.user.username %> has invited you to the website Lobster
To create an account, visit the URL below: To create an account, visit the URL below:
<%= @root_url %>invitations/<%= @invitation.code %> <%= root_url %>invitations/<%= @invitation.code %>

View file

@ -4,4 +4,4 @@ Someone at <%= @ip %> requested to reset your account password
on lobste.rs. If you submitted this request, visit the link below to on lobste.rs. If you submitted this request, visit the link below to
set a new password. If not, you can disregard this e-mail. set a new password. If not, you can disregard this e-mail.
<%= @root_url %>login/set_new_password?token=<%= @user.password_reset_token %> <%= root_url %>login/set_new_password?token=<%= @user.password_reset_token %>

23
extras/pushover.rb Normal file
View file

@ -0,0 +1,23 @@
class Pushover
cattr_accessor :API_KEY
# this needs to be overridden in config/initializers/production.rb
@@API_KEY = nil
def self.push(user, device, params)
if !@@API_KEY
return
end
begin
s = Sponge.new
s.fetch("https://api.pushover.net/1/messages.json", :post, {
:token => @@API_KEY,
:user => user,
:device => device
}.merge(params))
rescue => e
Rails.logger.error "error sending to pushover: #{e.inspect}"
end
end
end