Project

General

Profile

Feature #1354 ยป akismet.patch

Brad Beattie, 2009-05-15 20:15

View differences:

lib/akismet.rb (revision 0)
1
# Akismet
2
#
3
# Author:: David Czarnecki
4
# Copyright:: Copyright (c) 2005 - David Czarnecki
5
# License:: BSD
6
# Modified by Dieter Komendera, Sparkling Studios:
7
#   append blog= to data string (Akismet said it is required)
8
#   changed require 'net/HTTP' to require 'net/http' (to work for me unter GNU/Linux)
9
# Akismet Key - 4ebc7e35c512
10
class Akismet
11

  
12
  require 'net/http'
13
  require 'uri'
14
  
15
  STANDARD_HEADERS = {
16
    'User-Agent' => 'Akismet Ruby API/1.0',
17
    'Content-Type' => 'application/x-www-form-urlencoded'
18
  }
19
  
20
  # Create a new instance of the Akismet class
21
  #
22
  # apiKey 
23
  #   Your Akismet API key
24
  # blog 
25
  #   The blog associated with your api key
26
  def initialize(apiKey, blog)
27
    @apiKey = apiKey
28
    @blog = blog
29
  end
30
  
31
  # Set proxy information 
32
  #
33
  # proxyHost
34
  #   Hostname for the proxy to use
35
  # proxyPort
36
  #   Port for the proxy
37
  def setProxy(proxyHost, proxyPort) 
38
    @proxyPort = proxyPort
39
    @proxyHost = proxyHost
40
  end
41
  
42
  def valid?
43
    (!@apiKey.blank? && !@blog.blank? && verifyAPIKey)
44
  end
45
    
46
  # Call to check and verify your API key.
47
  def verifyAPIKey
48
    http = Net::HTTP.new('rest.akismet.com', 80, @proxyHost, @proxyPort)
49
    path = '/1.1/verify-key'
50
    
51
    data="key=#{@apiKey}&blog=#{@blog}"
52
    
53
    resp, data = http.post(path, data, STANDARD_HEADERS)
54
    (data == "valid")
55
  end
56
 
57
  # Internal call to Akismet. Prepares the data for posting to the Akismet service.
58
  #
59
  # akismet_function
60
  #   The Akismet function that should be called
61
  # user_ip (required)
62
  #    IP address of the comment submitter.
63
  # user_agent (required)
64
  #    User agent information.
65
  # referrer (note spelling)
66
  #    The content of the HTTP_REFERER header should be sent here.
67
  # permalink
68
  #    The permanent location of the entry the comment was submitted to.
69
  # comment_type
70
  #    May be blank, comment, trackback, pingback, or a made up value like "registration".
71
  # comment_author
72
  #    Submitted name with the comment
73
  # comment_author_email
74
  #    Submitted email address
75
  # comment_author_url
76
  #    Commenter URL.
77
  # comment_content
78
  #    The content that was submitted.
79
  # Other server enviroment variables
80
  #    In PHP there is an array of enviroment variables called $_SERVER which contains information about the web server itself as well as a key/value for every HTTP header sent with the request. This data is highly useful to Akismet as how the submited content interacts with the server can be very telling, so please include as much information as possible.  
81
  def callAkismet(akismet_function, user_ip, user_agent, referrer, permalink, comment_type, comment_author, comment_author_email, comment_author_url, comment_content, other)
82
    http = Net::HTTP.new("#{@apiKey}.rest.akismet.com", 80, @proxyHost, @proxyPort)
83
    path = "/1.1/#{akismet_function}"        
84
    
85
    data = "blog=#{@blog}&user_ip=#{user_ip}&user_agent=#{user_agent}&referrer=#{referrer}&permalink=#{permalink}&comment_type=#{comment_type}&comment_author=#{comment_author}&comment_author_email=#{comment_author_email}&comment_author_url=#{comment_author_url}&comment_content=#{comment_content}"
86
    if (other != nil) 
87
      other.each_pair {|key, value| data.concat("&#{key}=#{value}")}
88
    end
89
            
90
    resp, data = http.post(path, data, STANDARD_HEADERS)
91

  
92
    return (data != "false")
93
  end
94
  
95
  protected :callAkismet
96

  
97
  # This is basically the core of everything. This call takes a number of arguments and characteristics about the submitted content and then returns a thumbs up or thumbs down. Almost everything is optional, but performance can drop dramatically if you exclude certain elements.
98
  #
99
  # user_ip (required)
100
  #    IP address of the comment submitter.
101
  # user_agent (required)
102
  #    User agent information.
103
  # referrer (note spelling)
104
  #    The content of the HTTP_REFERER header should be sent here.
105
  # permalink
106
  #    The permanent location of the entry the comment was submitted to.
107
  # comment_type
108
  #    May be blank, comment, trackback, pingback, or a made up value like "registration".
109
  # comment_author
110
  #    Submitted name with the comment
111
  # comment_author_email
112
  #    Submitted email address
113
  # comment_author_url
114
  #    Commenter URL.
115
  # comment_content
116
  #    The content that was submitted.
117
  # Other server enviroment variables
118
  #    In PHP there is an array of enviroment variables called $_SERVER which contains information about the web server itself as well as a key/value for every HTTP header sent with the request. This data is highly useful to Akismet as how the submited content interacts with the server can be very telling, so please include as much information as possible.
119
  def commentCheck(user_ip, user_agent, referrer, permalink, comment_type, comment_author, comment_author_email, comment_author_url, comment_content, other)
120
    return callAkismet('comment-check', user_ip, user_agent, referrer, permalink, comment_type, comment_author, comment_author_email, comment_author_url, comment_content, other)
121
  end
122
  
123
  # This call is for submitting comments that weren't marked as spam but should have been. It takes identical arguments as comment check.
124
  # The call parameters are the same as for the #commentCheck method.
125
  def submitSpam(user_ip, user_agent, referrer, permalink, comment_type, comment_author, comment_author_email, comment_author_url, comment_content, other)
126
    callAkismet('submit-spam', user_ip, user_agent, referrer, permalink, comment_type, comment_author, comment_author_email, comment_author_url, comment_content, other)
127
  end
128
  
129
  # This call is intended for the marking of false positives, things that were incorrectly marked as spam. It takes identical arguments as comment check and submit spam.
130
  # The call parameters are the same as for the #commentCheck method.
131
  def submitHam(user_ip, user_agent, referrer, permalink, comment_type, comment_author, comment_author_email, comment_author_url, comment_content, other)
132
    callAkismet('submit-ham', user_ip, user_agent, referrer, permalink, comment_type, comment_author, comment_author_email, comment_author_url, comment_content, other)
133
  end
134
end
db/migrate/20090515104800_add_spam_columns.rb (revision 0)
1
class AddSpamColumns < ActiveRecord::Migration
2
  def self.up
3
    add_column :messages, :spam, :boolean, :default => false
4
  end
5

  
6
  def self.down
7
    remove_column :messages, :spam
8
  end
9
end
config/settings.yml (working copy)
153 153
  default: 0
154 154
openid:
155 155
  default: 0
156
akismet_api_key:
157
  default: 
app/views/settings/_general.rhtml (working copy)
38 38

  
39 39
<p><label><%= l(:setting_diff_max_lines_displayed) %></label>
40 40
<%= text_field_tag 'settings[diff_max_lines_displayed]', Setting.diff_max_lines_displayed, :size => 6 %></p>
41

  
42
<p><label><%= l(:setting_akismet_api_key) %></label>
43
<%= text_field_tag 'settings[akismet_api_key]', Setting.akismet_api_key, :size => 20 %></p>
41 44
</div>
42 45

  
43 46
<%= submit_tag l(:button_save) %>
app/models/message.rb (working copy)
45 45
  def validate_on_create
46 46
    # Can not reply to a locked topic
47 47
    errors.add_to_base 'Topic is locked' if root.locked? && self != root
48
    errors.add_to_base 'Spam blocked' if spam?
48 49
  end
49 50
  
50 51
  def after_create
......
87 88
  def add_author_as_watcher
88 89
    Watcher.create(:watchable => self.root, :user => author)
89 90
  end
91
  
92
  def akismet
93
    @akismet ||= Akismet.new(Setting.akismet_api_key, "<<<URL FOR THE SITE?>>>")
94
  end
95
  
96
  # If the Akismet details are valid, and Akismet thinks this is a non-spam
97
  # comment, this method will return true
98
  def spam?
99
    if akismet.valid?
100
      # We do the negation because true means spam, false means ham
101
      akismet.commentCheck(
102
        request.remote_ip,              # remote IP
103
        request.env['HTTP_USER_AGENT'], # user agent
104
        request.env['HTTP_REFERER'],    # http referer
105
        'comment',                      # comment type
106
        self.author.name.to_s,          # author name
107
        self.author.email,              # author email
108
        self.content,                   # comment text
109
        {}                              # other
110
      )
111
    else
112
      true
113
    end
114
  end
90 115
end
    (1-1/1)