public
Fork of halorgium/mephisto
Description: A refactored Mephisto that has multiple spam detection engines.
Homepage: http://mephistoblog.com/
Clone URL: git://github.com/francois/mephisto.git
technoweenie (author)
Fri Mar 30 21:07:57 -0700 2007
commit  6f644bee8b9698efd08d71b809f6f426e463df88
tree    5cf7f1320c5e6af72e7c24fed6cb1e5a8d292916
parent  f5e53e93a75f7d233ac77b769eb69ed0a2f2bf78
mephisto / app / models / comment.rb
100644 117 lines (98 sloc) 4.306 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
require 'uri'
 
class Comment < Content
  validates_presence_of :author, :author_ip, :article_id, :body
  validates_format_of :author_email, :with => Format::EMAIL
  before_validation :clean_up_author_email
  before_validation :clean_up_author_url
  after_validation_on_create :snag_article_attributes
  before_create :check_comment_expiration
  before_create :sanitize_attributes
  before_save :update_counter_cache
  before_destroy :decrement_counter_cache
  belongs_to :article
  has_one :event, :dependent => :destroy
  attr_accessible :article, :article_id, :user_id, :user, :excerpt, :body, :author, :author_url, :author_email, :author_ip, :updater_id, :updater, :comment_age, :user_agent, :referrer
 
  def self.find_all_by_section(section, options = {})
    find :all, options.update(:conditions => ['contents.approved = ? and assigned_sections.section_id = ?', true, section.id],
      :select => 'contents.*', :joins => 'INNER JOIN assigned_sections ON assigned_sections.article_id = contents.article_id',
      :order => 'contents.created_at DESC')
  end
 
  def to_liquid
    CommentDrop.new self
  end
  
  def approved=(value)
    @old_approved ||= approved? ? :true : :false
    write_attribute :approved, value
  end
 
  def clean_up_author_email
    if value = read_attribute(:author_email) then
      write_attribute :author_email, value.strip
    end
  end
 
  def clean_up_author_url
    if value = read_attribute(:author_url) then
      value.strip!
      value = 'http://' + value unless value.blank? || value[0..0] == '/' || URI::parse(value).scheme
      write_attribute :author_url, value
    end
  rescue URI::InvalidURIError
    write_attribute :author_url, nil
  end
 
  def article_referenced_cache_key
    "[#{article_id}:Article]"
  end
 
  def check_approval(site, request)
    self.approved = site.approve_comments?
    if valid_comment_system?(site)
      akismet = Akismet.new(site.akismet_key, site.akismet_url)
      self.approved = !akismet.comment_check(comment_spam_options(site, request))
      logger.info "Checking Akismet (#{site.akismet_key}) for new comment on Article #{article_id}. #{approved? ? 'Approved' : 'Blocked'}"
      logger.warn "Odd Akismet Response: #{akismet.last_response.inspect}" unless Akismet.normal_responses.include?(akismet.last_response)
    end
  end
 
  def mark_as_spam(site, request)
    mark_comment :spam, site, request
  end
  
  def mark_as_ham(site, request)
    mark_comment :ham, site, request
  end
 
  protected
    def sanitize_attributes
      [:author, :author_url, :author_email, :author_ip, :user_agent, :referrer].each do |a|
        self.send("#{a}=", CGI::escapeHTML(self.send(a).to_s))
      end
    end
 
    def snag_article_attributes
      self.filter ||= article.site.filter
      [:site, :title, :published_at, :permalink].each { |a| self.send("#{a}=", article.send(a)) }
    end
 
    def check_comment_expiration
      raise Article::CommentNotAllowed unless article.accept_comments?
    end
 
    def update_counter_cache
      Article.increment_counter 'comments_count', article_id if approved? && @old_approved == :false
      Article.decrement_counter 'comments_count', article_id if !approved? && @old_approved == :true
    end
    
    def decrement_counter_cache
      Article.decrement_counter 'comments_count', article_id if approved?
    end
    
    def valid_comment_system?(site)
      [:akismet_key, :akismet_url].all? { |attr| !site.send(attr).blank? }
    end
    
    def comment_spam_options(site, request)
      {:user_ip => author_ip,
       :user_agent => user_agent,
       :referrer => referrer,
       :permalink => "http://#{request.host_with_port}#{site.permalink_for(self)}",
       :comment_author => author,
       :comment_author_email => author_email,
       :comment_author_url => author_url,
       :comment_content => body}
    end
    
    def mark_comment(comment_type, site, request)
      if valid_comment_system?(site)
        response = Akismet.new(site.akismet_key, site.akismet_url).send("submit_#{comment_type}", comment_spam_options(site, request))
        logger.info "Calling Akismet (#{site.akismet_key}) for #{comment_type} comment on Article #{article_id}. #{response}"
      end
    end
end