rakismet 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +8 -0
- data/MIT-LICENSE +20 -0
- data/README.md +156 -0
- data/generators/rakismet/rakismet_generator.rb +7 -0
- data/generators/rakismet/templates/config/initializers/rakismet.rb +3 -0
- data/lib/rakismet.rb +69 -0
- data/lib/rakismet/controller_extensions.rb +26 -0
- data/lib/rakismet/model_extensions.rb +69 -0
- data/rails/init.rb +2 -0
- metadata +65 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
= 0.3.5
|
2
|
+
* Added gemspec and rails/init.rb so rakismet can work as a gem [michael]
|
3
|
+
* Added generator template and manifest [michael]
|
4
|
+
= 0.3.0
|
5
|
+
* Abstract out Rakismet version string
|
6
|
+
* Set default Akismet Host
|
7
|
+
* Abstract out the Akismet host [Mike Burns]
|
8
|
+
* Started keeping a changelog :P
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Josh French
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
Rakismet
|
2
|
+
========
|
3
|
+
|
4
|
+
**Akismet** (<http://akismet.com/>) is a collaborative spam filtering service.
|
5
|
+
**Rakismet** is easy Akismet integration with your Rails app, including support
|
6
|
+
for TypePad's AntiSpam service.
|
7
|
+
|
8
|
+
|
9
|
+
Setup
|
10
|
+
=====
|
11
|
+
|
12
|
+
As a plugin
|
13
|
+
-----------
|
14
|
+
|
15
|
+
Install with `script/plugin install git://github.com/jfrench/rakismet`
|
16
|
+
|
17
|
+
Rakismet installation should have created a file called rakismet.rb in
|
18
|
+
config/initializers. If not, you can copy the template from:
|
19
|
+
vendor/plugins/rakismet/generators/rakismet/templates/config/initializers/rakismet.rb.
|
20
|
+
|
21
|
+
As a gem
|
22
|
+
--------
|
23
|
+
|
24
|
+
`gem install rakismet` if you're using gemcutter or
|
25
|
+
`gem install jfrench-rakismet` if you're using GitHub.
|
26
|
+
|
27
|
+
From your app root, run `./script/generate rakismet` to create the Rakismet
|
28
|
+
initializer.
|
29
|
+
|
30
|
+
Getting Started
|
31
|
+
---------------
|
32
|
+
|
33
|
+
Once you've installed Rakismet via your method of choice, you'll need an API
|
34
|
+
key from the folks at WordPress. Head on over to http://wordpress.com/api-keys/
|
35
|
+
and sign up for a new username.
|
36
|
+
|
37
|
+
Edit config/initializers/rakismet.rb and fill in `Rakismet::URL` and
|
38
|
+
`Rakismet::KEY` with the URL of your application and the key you received
|
39
|
+
from WordPress.
|
40
|
+
|
41
|
+
If you wish to use another Akismet-compatible API provider such as TypePad's
|
42
|
+
antispam service, you'll also need to change the `Rakismet::HOST`.
|
43
|
+
|
44
|
+
Finally, introduce Rakismet to your application. Let's assume you have a Comment
|
45
|
+
model and a CommentsController:
|
46
|
+
|
47
|
+
class Comment < ActiveRecord::Base
|
48
|
+
has_rakismet
|
49
|
+
end
|
50
|
+
|
51
|
+
class CommentsController < ActionController::Base
|
52
|
+
has_rakismet
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
Basic Usage
|
57
|
+
===========
|
58
|
+
|
59
|
+
Rakismet provides three methods for interacting with Akismet:
|
60
|
+
|
61
|
+
`spam?`
|
62
|
+
|
63
|
+
From within a CommentsController action, simply call `@comment.spam?` to get a
|
64
|
+
true/false response. True means it's spam, false means it's not. Well,
|
65
|
+
usually; it's possible something went wrong and Akismet returned an error
|
66
|
+
message. `@comment.spam?` will return false if this happens. You can check
|
67
|
+
`@comment.akismet_response` to be certain; anything other than 'true' or
|
68
|
+
'false' means you got an error. That said, as long as you're collecting the
|
69
|
+
data listed above it's probably sufficient to check `spam?` alone.
|
70
|
+
|
71
|
+
`ham!` and `spam!`
|
72
|
+
|
73
|
+
Akismet works best with your feedback. If you spot a comment that was
|
74
|
+
erroneously marked as spam, `@comment.ham!` will resubmit to Akismet, marked
|
75
|
+
as a false positive. Likewise if they missed a spammy comment,
|
76
|
+
`@comment.spam!` will resubmit marked as spam.
|
77
|
+
|
78
|
+
|
79
|
+
What's Required in the Comment Model?
|
80
|
+
=====================================
|
81
|
+
|
82
|
+
Rakismet sends the following information to the spam-hungry robots at Akismet.
|
83
|
+
This means these attributes should be stored in your Comment model or
|
84
|
+
accessible through that class's associations.
|
85
|
+
|
86
|
+
author : name submitted with the comment
|
87
|
+
author_url : URL submitted with the comment
|
88
|
+
author_email : email submitted with the comment
|
89
|
+
comment_type : 'comment', 'trackback', 'pingback', or whatever you fancy
|
90
|
+
content : the content submitted
|
91
|
+
permalink : the permanent URL for the entry the comment belongs to
|
92
|
+
user_ip : IP address used to submit this comment
|
93
|
+
user_agent : user agent string
|
94
|
+
referrer : http referer
|
95
|
+
|
96
|
+
`user_ip`, `user_agent`, and `referrer` are optional; you don't have to store
|
97
|
+
them, but it's a good idea. If you omit them from your model (see "Customizing
|
98
|
+
Attributes"), the `spam?` method will attempt to extract these values from the
|
99
|
+
current request object, if there is one. This means Rakismet can operate
|
100
|
+
asynchronously by storing the request attributes and validating the comment at
|
101
|
+
a later time. Or it can operate synchronously by plucking the request
|
102
|
+
attributes from the environment at the time the comment is initially submitted
|
103
|
+
and validating on the spot. The latter could work well with a before_create
|
104
|
+
callback.
|
105
|
+
|
106
|
+
|
107
|
+
Customizing the Comment Model
|
108
|
+
=============================
|
109
|
+
|
110
|
+
If your attribute names don't match those listed above, or if some of them
|
111
|
+
live on other objects, you can pass `has_rakismet` a hash mapping the default
|
112
|
+
attributes to your own. You can change the names, if your comment attributes
|
113
|
+
don't match the defaults:
|
114
|
+
|
115
|
+
class Comment < ActiveRecord::Base
|
116
|
+
has_rakismet :author => :commenter_name,
|
117
|
+
:author_email => :commenter_email
|
118
|
+
end
|
119
|
+
|
120
|
+
Or you can pass in a proc, to access associations:
|
121
|
+
|
122
|
+
class Comment < ActiveRecord::Base
|
123
|
+
belongs_to :author
|
124
|
+
has_rakismet :author => proc { author.name },
|
125
|
+
:author_email => proc { author.email }
|
126
|
+
end
|
127
|
+
|
128
|
+
For any attribute you don't specify, Rakismet will try to find an attribute or
|
129
|
+
method matching the default name. As mentioned above, if `user_ip`,
|
130
|
+
`user_agent`, and `referrer` are not present on your model, Rakismet will
|
131
|
+
attempt to find them in the request environment when `spam?` is called from
|
132
|
+
within a Rakismet-aware controller action.
|
133
|
+
|
134
|
+
Customizing the Comments Controller
|
135
|
+
===================================
|
136
|
+
|
137
|
+
Most of the time you won't be checking for spam on every action defined in
|
138
|
+
your controller. If you only call `spam?` within `CommentsController#create`
|
139
|
+
and you'd like to reduce filter overhead, `has_rakismet` takes `:only` and
|
140
|
+
`:except` parameters that work like the standard before/around/after filter
|
141
|
+
options.
|
142
|
+
|
143
|
+
class CommentsController < ActionController::Base
|
144
|
+
has_rakismet :only => :create
|
145
|
+
end
|
146
|
+
|
147
|
+
Forked
|
148
|
+
=============================
|
149
|
+
|
150
|
+
At the time of forking, the only addition to this project has been to add gemspec
|
151
|
+
and generator templates so rakismet can be used as a gem. This is a better solution
|
152
|
+
when working with reloadable plugins as rakismet is not compatible when plugins are
|
153
|
+
reloadable.
|
154
|
+
|
155
|
+
--------------------------------------------------------------
|
156
|
+
Copyright (c) 2008 Josh French, released under the MIT license
|
data/lib/rakismet.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Rakismet
|
5
|
+
module Version
|
6
|
+
Major = '0'
|
7
|
+
Minor = '3'
|
8
|
+
Tiny = '5'
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.version
|
12
|
+
[Version::Major, Version::Minor, Version::Tiny].join('.')
|
13
|
+
end
|
14
|
+
|
15
|
+
class Base
|
16
|
+
cattr_accessor :valid_key, :rakismet_binding
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def validate_key
|
20
|
+
validate_constants
|
21
|
+
akismet = URI.parse(verify_url)
|
22
|
+
_, valid = Net::HTTP.start(akismet.host) do |http|
|
23
|
+
data = "key=#{Rakismet::KEY}&blog=#{Rakismet::URL}"
|
24
|
+
http.post(akismet.path, data, Rakismet::HEADERS)
|
25
|
+
end
|
26
|
+
self.valid_key = (valid == 'valid')
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid_key?
|
30
|
+
@@valid_key == true
|
31
|
+
end
|
32
|
+
|
33
|
+
def akismet_call(function, args={})
|
34
|
+
validate_constants
|
35
|
+
args.merge!(:blog => Rakismet::URL)
|
36
|
+
akismet = URI.parse(call_url(function))
|
37
|
+
_, response = Net::HTTP.start(akismet.host) do |http|
|
38
|
+
data = args.map { |k,v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')
|
39
|
+
http.post(akismet.path, data, Rakismet::HEADERS)
|
40
|
+
end
|
41
|
+
response
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def verify_url
|
47
|
+
"http://#{Rakismet::HOST}/1.1/verify-key"
|
48
|
+
end
|
49
|
+
|
50
|
+
def call_url(function)
|
51
|
+
"http://#{Rakismet::KEY}.#{Rakismet::HOST}/1.1/#{function}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def validate_constants
|
55
|
+
raise Undefined, "Rakismet::KEY is not defined" if Rakismet::KEY.blank?
|
56
|
+
raise Undefined, "Rakismet::URL is not defined" if Rakismet::URL.blank?
|
57
|
+
raise Undefined, "Rakismet::HOST is not defined" if Rakismet::HOST.blank?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Undefined = Class.new(NameError)
|
63
|
+
NoBinding = Class.new(NameError)
|
64
|
+
|
65
|
+
HEADERS = {
|
66
|
+
'User-Agent' => "Rails/#{Rails::VERSION::STRING} | Rakismet/#{Rakismet.version}",
|
67
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
68
|
+
}
|
69
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Rakismet
|
2
|
+
module ControllerExtensions
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
extend ClassMethods
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def rakismet(&block)
|
11
|
+
Rakismet::Base.rakismet_binding = binding
|
12
|
+
yield
|
13
|
+
Rakismet::Base.rakismet_binding = nil
|
14
|
+
end
|
15
|
+
private :rakismet
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
def has_rakismet(opts={})
|
19
|
+
skip_filter :rakismet # in case we're inheriting from another Rakismeted controller
|
20
|
+
opts.assert_valid_keys(:only, :except)
|
21
|
+
self.around_filter :rakismet, opts
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Rakismet
|
2
|
+
module ModelExtensions
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
attr_accessor :akismet_response
|
7
|
+
class_inheritable_hash :akismet_attrs
|
8
|
+
extend ClassMethods
|
9
|
+
include InstanceMethods
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def has_rakismet(args={})
|
15
|
+
self.akismet_attrs ||= {}
|
16
|
+
[:comment_type, :author, :author_url, :author_email, :content].each do |field|
|
17
|
+
# clunky, but throwing around +type+ will break your heart
|
18
|
+
fieldname = field.to_s =~ %r(^comment_) ? field : "comment_#{field}".intern
|
19
|
+
self.akismet_attrs[fieldname] = args.delete(field) || field
|
20
|
+
end
|
21
|
+
[:user_ip, :user_agent, :referrer].each do |field|
|
22
|
+
self.akismet_attrs[field] = (args.delete(field) || field) if args.has_key?(field) or self.public_instance_methods.include?(field.to_s)
|
23
|
+
end
|
24
|
+
args.each_pair do |f,v|
|
25
|
+
self.akismet_attrs[f] = v
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module InstanceMethods
|
31
|
+
def spam?
|
32
|
+
data = akismet_data
|
33
|
+
|
34
|
+
unless Rakismet::Base.rakismet_binding.nil?
|
35
|
+
{ :referrer => 'request.referer', :user_ip => 'request.remote_ip',
|
36
|
+
:user_agent => 'request.user_agent' }.each_pair do |k,v|
|
37
|
+
data[k] = eval(v, Rakismet::Base.rakismet_binding) || ''
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
self.akismet_response = Rakismet::Base.akismet_call('comment-check', data)
|
42
|
+
self.akismet_response == 'true'
|
43
|
+
end
|
44
|
+
|
45
|
+
def spam!
|
46
|
+
Rakismet::Base.akismet_call('submit-spam', akismet_data)
|
47
|
+
end
|
48
|
+
|
49
|
+
def ham!
|
50
|
+
Rakismet::Base.akismet_call('submit-ham', akismet_data)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def akismet_data
|
56
|
+
self.class.akismet_attrs.keys.inject({}) do |data,attr|
|
57
|
+
data.merge attr => if self.class.akismet_attrs[attr].is_a?(Proc)
|
58
|
+
instance_eval(&self.class.akismet_attrs[attr])
|
59
|
+
elsif respond_to?(self.class.akismet_attrs[attr])
|
60
|
+
send(self.class.akismet_attrs[attr])
|
61
|
+
else
|
62
|
+
self.class.akismet_attrs[attr]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
data/rails/init.rb
ADDED
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rakismet
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Josh French
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-16 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Rakismet is easy Akismet integration with your Rails app, including support for TypePad's AntiSpam service.
|
17
|
+
email: systems@inspiredigital.com.au
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.md
|
24
|
+
- MIT-LICENSE
|
25
|
+
files:
|
26
|
+
- CHANGELOG
|
27
|
+
- README.md
|
28
|
+
- MIT-LICENSE
|
29
|
+
- rails/init.rb
|
30
|
+
- lib/rakismet.rb
|
31
|
+
- lib/rakismet/controller_extensions.rb
|
32
|
+
- lib/rakismet/model_extensions.rb
|
33
|
+
- generators/rakismet/rakismet_generator.rb
|
34
|
+
- generators/rakismet/templates/config/initializers/rakismet.rb
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://github.com/jfrench/rakismet
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options:
|
41
|
+
- --inline-source
|
42
|
+
- --charset=UTF-8
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project: rakismet
|
60
|
+
rubygems_version: 1.3.4
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: Rakismet is easy Akismet integration with your Rails app, including support for TypePad's AntiSpam service.
|
64
|
+
test_files: []
|
65
|
+
|