akismet 1.0.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21be3c8269a6a3727bbe1760d106b450cb7bc48d
4
- data.tar.gz: 92ff9426460df5eed3b240d577375323f0a668c4
3
+ metadata.gz: 00663d1516528ee39d7e814ea5393f177802be86
4
+ data.tar.gz: 99dccbfcabb40bd23a8e9239503eee9885e6c4f3
5
5
  SHA512:
6
- metadata.gz: 82c9fbcc9d514619e2c19c3a4b12625e7e8744b98746910346fd562bc527401ff22d7fa0871fd785af44697375ed261645a599acd5471e75dec4f95b97e40d54
7
- data.tar.gz: 0f5f1f79dd1525f89627a41f857d78713ccfd3ff69aae9c6ac7e8be85777165a822a4e959c997427d5727e5b85d914fea564f1ce138e9cd70fc1ff98c2dfaa33
6
+ metadata.gz: d235bdf6c5346a477295d3285d8fcfd56079edead6287b7001e1f5e4d6156920480fa4e066a8e8bcf12ba78f34a533b762e11b9c85068e1fee5faea47a6212ad
7
+ data.tar.gz: bcadc97707e2fe6a250e9cce4f2093cb3e6303a26536d9527a3eb07710cc79802c1663e6b13f77a8b5ea697c7ddb8053e27bda282427acdace04c9282803751a
@@ -0,0 +1,4 @@
1
+ --no-private
2
+ -
3
+ README.md
4
+ LICENSE.txt
File without changes
data/README.md CHANGED
@@ -1,68 +1,123 @@
1
- Akismet
2
- =======
3
-
4
- A Ruby client for the Akismet API.
5
-
6
- Instantiate an `Akismet::Client` with your API key and home page URL. Then
7
- call `verify_key`, `comment_check`, `submit_ham`, or `submit_spam`.
8
-
9
- Use `Akismet::Client.open` or `Akismet::Client#open` to submit multiple
10
- requests over a single TCP connection.
11
-
12
- See lib/akismet/client.rb for more documentation or generate docs with YARD.
13
-
14
- Verify an API key
15
- -----------------
16
-
17
- Akismet::Client.new( 'apikey123', 'http://jonahb.com' ).verify_key
18
-
19
-
20
- Check whether a comment is spam
21
- -------------------------------
22
-
23
- client = Akismet::Client.new( 'apikey123',
24
- 'http://jonahb.com',
25
- :app_name => 'jonahb.com',
26
- :app_version => '1.0' )
27
-
28
- # assumes variables comment, post_url, request (a racklike HTTP request)
29
- spam = client.comment_check( request.remote_ip,
30
- request.user_agent,
31
- :content_type => 'comment',
32
- :referrer => request.headers[ 'HTTP_REFERER' ],
33
- :permalink => post_url,
34
- :comment_author => comment.author,
35
- :comment_author_email => comment.author_email,
36
- :comment_content => comment.body )
37
-
38
- if spam
39
- # ...
40
- end
41
-
42
- Submit a batch of checks using a single TCP connection
43
- ------------------------------------------------------
44
-
45
- client = Akismet::Client.new( 'apikey123',
46
- 'http://jonahb.com',
47
- :app_name => 'jonahb.com',
48
- :app_version => '1.0' )
49
-
50
- begin
51
- client.open
52
- comments.each do |comment|
53
- client.comment_check( ... ) # see example above
54
- end
55
- ensure
56
- client.close
57
- end
58
-
59
- # ... or ...
60
-
61
- Akismet::Client.open( 'apikey123',
62
- 'http://jonahb.com',
63
- :app_name => 'jonahb.com',
64
- :app_version => '1.0' ) do |client|
65
- comments.each do |comment|
66
- client.comment_check( ... ) # see example above
67
- end
68
- end
1
+ # akismet
2
+
3
+ A Ruby client for the [Akismet API](http://akismet.com/development/api/).
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/akismet.svg)](http://badge.fury.io/rb/akismet)
6
+ [![Build Status](https://travis-ci.org/jonahb/akismet.svg?branch=master)](https://travis-ci.org/jonahb/akismet)
7
+
8
+ ## Getting Started
9
+
10
+ ### Installation
11
+
12
+ ```bash
13
+ gem install akismet
14
+ ```
15
+
16
+ ### Documentation
17
+
18
+ This README provides an overview of `akismet`. Full documentation is
19
+ available at [rubydoc.info](http://www.rubydoc.info/gems/akismet).
20
+
21
+ ### API Key
22
+
23
+ Sign up at [akismet.com](https://akismet.com/) and retrieve your API
24
+ key from your [account page](https://akismet.com/account/).
25
+
26
+ ## Usage
27
+
28
+ ### Basics
29
+
30
+ Set your API key and app URL (a URL representing your app):
31
+
32
+ ```ruby
33
+ Akismet.api_key = '<your API key>'
34
+ Akismet.app_url = 'http://example.com'
35
+ ```
36
+
37
+ Then check whether a comment is spam ...
38
+
39
+ ```ruby
40
+ # request is a Rack::Request
41
+ is_spam = Akismet.spam?(request.ip, request.user_agent, text: 'Poppycock!')
42
+ ```
43
+
44
+ ... file a spam report ...
45
+
46
+ ```ruby
47
+ Akismet.spam request.ip, request.user_agent, text: 'I earn $2,000 a week ...'
48
+ ```
49
+
50
+ ... or flag a false positive ("ham" is not-spam):
51
+
52
+ ```ruby
53
+ Akismet.ham request.ip, request.user_agent, text: '"Viagra" derives from the Sanskrit ...'
54
+ ```
55
+
56
+ ### Accuracy
57
+
58
+ To maximize the accuracy of the filter, submit as many of the [documented](http://www.rubydoc.info/gems/akismet) parameters as possible. Also submit environment variables related to the comment as a hash in the `env` parameter (Akismet suggests [these variables](http://php.net/manual/en/reserved.variables.server.php)):
59
+
60
+ ```ruby
61
+ vars = %w{
62
+ HTTP_ACCEPT
63
+ HTTP_ACCEPT_ENCODING
64
+ # ...
65
+ }
66
+
67
+ params = {
68
+ type: 'comment',
69
+ text: 'A new life awaits you in the Off-World colonies.',
70
+ created_at: DateTime.now,
71
+ author: 'Eldon',
72
+ author_email: 'eldont@aol.com',
73
+ author_url: 'http://geocities.com/eldont',
74
+ post_url: 'http://example.com/posts/1',
75
+ post_modified_at: DateTime.new(2015, 1, 1),
76
+ referrer: request.referrer,
77
+ env: request.env.slice(*vars) # slice courtesy of Active Support
78
+ }
79
+
80
+ is_spam = Akismet.spam?(request.ip, request.user_agent, params)
81
+ ```
82
+ ### Blatant Spam
83
+
84
+ Akismet flags blatant spam that should be deleted without review. This feature is exposed via `Akismet.check`:
85
+
86
+ ```ruby
87
+ is_spam, is_blatant = Akismet.check(request.ip, request.user_agent, text: 'Buy everything ... now!')
88
+ ```
89
+
90
+ ### Reusing Connections
91
+
92
+ `Akismet.spam?` and friends create a new TCP connection each time you call them. If you have many comments to check or report, use `Akismet.open` to reuse a single connection:
93
+
94
+ ```ruby
95
+ Akismet.open do |client|
96
+ for comment in comments
97
+ is_spam = client.spam?(comment.ip, comment.user_agent, text: comment.text)
98
+ end
99
+ end
100
+ ```
101
+
102
+ ### Akismet::Client
103
+
104
+ In the example above, the object yielded to the block is an `Akismet::Client`. `Akismet::Client` underlies the `Akismet` class methods. Use it on its own to manually open and close connections or override the global API key:
105
+
106
+ ```ruby
107
+ begin
108
+ client = Akismet::Client.new('api-key-2', 'http://example2.com')
109
+ client.open
110
+ client.spam request.ip, request.user_agent, text: 'Bank error in your favor!'
111
+ ensure
112
+ client.close
113
+ end
114
+ ```
115
+
116
+ ## Tests
117
+
118
+ 1. Set the environment variable AKISMET\_API\_KEY to your API key
119
+ 2. `rake`
120
+
121
+ ## Contributing
122
+
123
+ Please submit issues and pull requests to [jonahb/akismet](https://github.com/jonahb/akismet) on GitHub.
@@ -3,5 +3,65 @@
3
3
  error
4
4
  client
5
5
  }.each do |file|
6
- require File.join( File.dirname( __FILE__ ), 'akismet', file )
7
- end
6
+ require "akismet/#{file}"
7
+ end
8
+
9
+ # {Akismet} provides convenience methods that instantiate a {Akismet::Client}
10
+ # and invoke the Akismet API in one call. Before calling these methods, set
11
+ # {api_key} and {app_url}.
12
+ #
13
+ module Akismet
14
+ class << self
15
+
16
+ # The API key obtained at akismet.com. Set before calling the {Akismet}
17
+ # class methods.
18
+ # @return [String]
19
+ attr_accessor :api_key
20
+
21
+ # A URL that identifies the application making the request. Set before
22
+ # calling the {Akismet} class methods.
23
+ # @return [String]
24
+ attr_accessor :app_url
25
+
26
+ # The name of the application making the request
27
+ # @return [String]
28
+ attr_accessor :app_name
29
+
30
+ # The version of the application making the request
31
+ # @return [String]
32
+ attr_accessor :app_version
33
+
34
+ # (see Client#check)
35
+ def check(user_ip, user_agent, params = {})
36
+ with_client { |client| client.check user_ip, user_agent, params }
37
+ end
38
+
39
+ # (see Client#spam?)
40
+ def spam?(user_ip, user_agent, params = {})
41
+ with_client { |client| client.spam? user_ip, user_agent, params }
42
+ end
43
+
44
+ # (see Client#spam)
45
+ def spam(user_ip, user_agent, params = {})
46
+ with_client { |client| client.spam user_ip, user_agent, params }
47
+ end
48
+
49
+ # (see Client#ham)
50
+ def ham(user_ip, user_agent, params = {})
51
+ with_client { |client| client.ham user_ip, user_agent, params }
52
+ end
53
+
54
+ # (see Client.open)
55
+ def open(&block)
56
+ with_client(&block)
57
+ end
58
+
59
+ private
60
+
61
+ def with_client(&block)
62
+ raise "Set Akismet.api_key" unless api_key
63
+ raise "Set Akismet.app_url" unless app_url
64
+ Akismet::Client.open api_key, app_url, app_name: app_name, app_version: app_version, &block
65
+ end
66
+ end
67
+ end
@@ -1,166 +1,108 @@
1
+ require 'date'
1
2
  require 'net/http'
2
- require 'cgi'
3
+ require 'uri'
3
4
 
4
5
  module Akismet
5
6
 
6
- # A Ruby client for the Akismet API.
7
- #
8
- # @example
9
- #
10
- # # Verify an API key
11
- # #
12
- #
13
- # Akismet::Client.new( 'apikey123', 'http://jonahb.com' ).verify_key
14
- #
15
- # @example
16
- #
17
- # # Check whether a comment is spam
18
- # #
19
- #
20
- # client = Akismet::Client.new( 'apikey123',
21
- # 'http://jonahb.com',
22
- # :app_name => 'jonahb.com',
23
- # :app_version => '1.0' )
24
- #
25
- # # assumes variables comment, post_url, request (a racklike HTTP request)
26
- # spam = client.comment_check( request.remote_ip,
27
- # request.user_agent,
28
- # :content_type => 'comment',
29
- # :referrer => request.headers[ 'HTTP_REFERER' ],
30
- # :permalink => post_url,
31
- # :comment_author => comment.author,
32
- # :comment_author_email => comment.author_email,
33
- # :comment_content => comment.body )
34
- #
35
- # if spam
36
- # # ...
37
- # end
38
- #
39
- # @example
40
- #
41
- # # Submit a batch of checks using a single TCP connection
42
- # #
43
- #
44
- #
45
- # client = Akismet::Client.new( 'apikey123',
46
- # 'http://jonahb.com',
47
- # :app_name => 'jonahb.com',
48
- # :app_version => '1.0' )
49
- #
50
- # begin
51
- # client.open
52
- # comments.each do |comment|
53
- # client.comment_check( ... ) # see example above
54
- # end
55
- # ensure
56
- # client.close
57
- # end
58
- #
59
- # # ... or ...
60
- #
61
- # Akismet::Client.open( 'apikey123',
62
- # 'http://jonahb.com',
63
- # :app_name => 'jonahb.com',
64
- # :app_version => '1.0' ) do |client|
65
- # comments.each do |comment|
66
- # client.comment_check( ... ) # see example above
67
- # end
68
- # end
69
- #
70
- #
71
7
  class Client
72
8
 
73
- # The API key obtained at akismet.com.
9
+ # The API key obtained at akismet.com
74
10
  # @return [String]
75
- #
76
11
  attr_reader :api_key
77
12
 
78
-
79
- # The URL of the home page of the application making the request.
13
+ # A URL that identifies the application making the request
80
14
  # @return [String]
81
- #
82
- attr_reader :home_url
15
+ attr_reader :app_url
83
16
 
84
-
85
- # The name of the application making the request, e.g "jonahb.com".
17
+ # The name of the application making the request
86
18
  # @return [String]
87
- #
88
19
  attr_reader :app_name
89
20
 
90
-
91
- # The version of the application making the request, e.g. "1.0".
21
+ # The version of the application making the request
92
22
  # @return [String]
93
- #
94
23
  attr_reader :app_version
95
24
 
25
+ # @!group Constructors
96
26
 
97
27
  # @param [String] api_key
98
- # The API key obtained at akismet.com.
99
- # @param [String] home_url
100
- # The URL of the home page of the application making the request.
28
+ # The API key obtained at akismet.com
29
+ # @param [String] app_url
30
+ # The URL of the home page of the application making the request
101
31
  # @option options [String] :app_name
102
32
  # The name of the application making the request, e.g. "jonahb.com".
103
33
  # Forms part of the User-Agent header submitted to Akismet.
104
34
  # @option options [String] :app_version
105
35
  # The version of the application making the request, e.g. "1.0". Forms
106
36
  # part of the User-Agent header submitted to Akismet. Ignored if
107
- # :app_name is not privded.
37
+ # :app_name is not provided.
108
38
  #
109
- def initialize( api_key, home_url, options = {} )
39
+ def initialize(api_key, app_url, options = {})
110
40
  @api_key = api_key
111
- @home_url = home_url
41
+ @app_url = app_url
112
42
  @app_name = options[ :app_name ]
113
43
  @app_version = options[ :app_version ]
44
+ @http_session = nil
114
45
  end
115
46
 
47
+ # @!group Managing Connections
116
48
 
117
- # Yields a new open Client, closing the Client when the block returns.
118
- # Takes the same arguments as {#initialize}. Use for submitting a batch of
119
- # requests using a single TCP and HTTP session.
120
- #
121
- # @yield [Akismet::Client]
122
- # @return [nil]
123
- # @see #initialize
49
+ # Initializes a client, opens it, yields it to the given block, and closes
50
+ # it when the block returns. Allows you to perform several operations over
51
+ # a single TCP connection.
52
+ # @param (see #initialize)
53
+ # @option (see #initialize)
54
+ # @yieldparam [Client] client
55
+ # @return [Object]
56
+ # The return value of the block
124
57
  # @see #open
125
58
  #
126
- def self.open( api_key, home_url, options = {} )
59
+ def self.open(api_key, app_url, options = {})
127
60
  raise "Block required" unless block_given?
128
- client = nil
129
- begin
130
- client = new( api_key, home_url, options )
131
- client.open
132
- yield client
133
- ensure
134
- client.close if client
135
- end
136
- nil
61
+ client = new(api_key, app_url)
62
+ client.open { yield client }
137
63
  end
138
64
 
139
-
140
- # Opens the client. You may use this method in combination with {#close}
141
- # to submit a batch of requests using a single TCP and HTTP session.
65
+ # Opens the client, creating a new TCP connection.
142
66
  #
143
- # If you don't call this before calling {#comment_check}, {#submit_ham},
144
- # or {#submit_spam}, a session will be created and opened for the duration
145
- # of the call.
67
+ # If a block is given, yields to the block, closes the client when the
68
+ # block returns, and returns the return value of the block. If a
69
+ # block is not given, returns self and leaves the client open, relying on
70
+ # the caller to close the client with {#close}.
146
71
  #
147
- # Note that calls to {#verify_key} always create a session. This is due to
148
- # a peculiarity of the Akismet API where {#verify_key} requests must be
149
- # sent to a different host.
72
+ # Note that opening and closing the client is only required if you want to
73
+ # make several calls over one TCP connection. Otherwise, you can simply
74
+ # call {#spam?}, {#check}, {#ham}, or {#spam}, which call {#open} for you
75
+ # if necessary.
150
76
  #
151
- # @return [self]
152
- # @raise [RuntimeError]
153
- # The client is already open.
154
- # @see #close
155
- # @see Akismet::Client.open
77
+ # Due to a peculiarity of the Akismet API, {#verify_key} always creates its
78
+ # own connection.
79
+ #
80
+ # @overload open
81
+ # Opens the client, yields to the block, and closes the client when the
82
+ # block returns.
83
+ # @yield
84
+ # A block to be called when the client is open
85
+ # @return [Object]
86
+ # The return value of the block
87
+ # @raise [StandardError]
88
+ # The client is already open
89
+ # @overload open
90
+ # @return [self]
91
+ # @raise [StandardError]
92
+ # The client is already open
156
93
  #
157
94
  def open
158
95
  raise "Already open" if open?
96
+
159
97
  @http_session = Net::HTTP.new( "#{ api_key }.rest.akismet.com", 80 )
160
- @http_session.start
161
- self
162
- end
163
98
 
99
+ begin
100
+ @http_session.start
101
+ block_given? ? yield : self
102
+ ensure
103
+ close if block_given?
104
+ end
105
+ end
164
106
 
165
107
  # Closes the Client.
166
108
  # @return [self]
@@ -172,122 +114,141 @@ module Akismet
172
114
  self
173
115
  end
174
116
 
175
-
176
117
  # Whether the Client is open.
177
- # @return [boolean]
118
+ # @return [Boolean]
178
119
  #
179
120
  def open?
180
121
  @http_session && @http_session.started?
181
122
  end
182
123
 
124
+ # @!group Verifying Keys
183
125
 
184
126
  # Checks the validity of the API key.
185
- # @return [boolean]
127
+ # @return [Boolean]
186
128
  #
187
129
  def verify_key
188
- response = Net::HTTP.start( 'rest.akismet.com', 80 ) do |session|
189
- invoke( session, 'verify-key', :blog => home_url, :key => api_key )
130
+ response = Net::HTTP.start('rest.akismet.com', 80) do |session|
131
+ invoke session, 'verify-key', blog: app_url, key: api_key
190
132
  end
191
133
 
192
- unless %w{ valid invalid }.include?( response.body )
134
+ unless %w{ valid invalid }.include?(response.body)
193
135
  raise_with_response response
194
136
  end
195
137
 
196
138
  response.body == 'valid'
197
139
  end
198
140
 
199
-
200
- # Checks whether a comment is spam. You are encouraged the submit, in
201
- # addition to the documented parameters, data about the client and the
202
- # comment submission. For example, if the client is an HTTP server,
203
- # include HTTP headers and environment variables.
141
+ # @!macro akismet_method
142
+ # @param [String] user_ip
143
+ # The comment author's IP address
144
+ # @param [String] user_agent
145
+ # The comment author's user-agent
146
+ # @param [Hash{Symbol => Object}] params
147
+ # Optional parameters. To maximize accuracy, pass as many as possible.
148
+ # @option params [String] :referrer
149
+ # The value of the HTTP_REFERER header. Note that the parameter is
150
+ # spelled with two consecutive 'r's.
151
+ # @option params [String] :post_url
152
+ # The URL of the post, article, etc. on which the comment was made
153
+ # @option params [DateTime] :post_modified_at
154
+ # The date and time the post was last modified
155
+ # @option params [String] :type
156
+ # Suggested values include 'comment', 'trackback', and 'pingback'
157
+ # @option params [String] :text
158
+ # The text of the comment
159
+ # @option params [DateTime] :created_at
160
+ # The date and time the comment was created
161
+ # @option params [String] :author
162
+ # The comment author's name
163
+ # @option params [String] :author_email
164
+ # The comment author's email address
165
+ # @option params [String] :author_url
166
+ # The comment author's personal URL
167
+ # @option params [Array<String>] :languages
168
+ # The ISO 639-1 codes of the languages in use on the site where the
169
+ # comment appears
170
+ # @option params [Boolean] :test
171
+ # When set to true, Akismet does not use the comment to train the filter
172
+ # @option params [Hash{Symbol, String => Object}] :env
173
+ # Environment variables such as HTTP headers related to the comment
174
+ # submission
175
+ # @raise [Akismet::Error]
176
+ # The Akismet service returned an error
177
+ # @raise [ArgumentError]
178
+ # An environment variable conflicts with a built-in parameter
179
+ # @raise [ArgumentError]
180
+ # Invalid param
181
+
182
+ # @!group Checking
183
+
184
+ # Checks whether a comment is spam and whether it is "blatant."
185
+ # @!macro akismet_method
186
+ # @return [(Boolean, Boolean)]
187
+ # An array containing two booleans. The first indicates whether the
188
+ # comment is spam. The second indicates whether it is "blatant,"
189
+ # i.e. whether it can be deleted without review.
204
190
  #
205
- # If the Client is not open, opens it for the duration of the call.
206
- #
207
- # @return [boolean]
208
- # @raise [Akismet::Error]
209
- # @param [String] user_ip
210
- # The IP address of the submitter of the comment.
211
- # @param [String] user_agent
212
- # The user agent of the web browser submitting the comment. Typically
213
- # the HTTP_USER_AGENT CGI variable. Not to be confused with the user
214
- # agent of the Akismet library.
215
- # @option params [String] :referrer
216
- # The value of the HTTP_REFERER header. Note that the parameter is
217
- # spelled with two consecutive 'r's.
218
- # @option params [String] :permalink
219
- # The permanent URL of the entry to which the comment pertains.
220
- # @option params [String] :comment_type
221
- # 'comment', 'trackback', 'pingback', or a made-up value like
222
- # 'registration'
223
- # @option params [String] :comment_author
224
- # The name of the author of the comment.
225
- # @option params [String] :comment_author_email
226
- # The email address of the author of the comment.
227
- # @option params [String] :comment_author_url
228
- # A URL submitted with the comment.
229
- # @option params [String] :comment_content
230
- # The text of the comment.
231
- #
232
- def comment_check( user_ip, user_agent, params = {} )
233
- response = invoke_comment_method( 'comment-check',
191
+ def check(user_ip, user_agent, params = {})
192
+ response = invoke_comment_method('comment-check',
234
193
  user_ip,
235
194
  user_agent,
236
- params )
195
+ params)
237
196
 
238
- unless %w{ true false }.include?( response.body )
197
+ unless %w{ true false }.include?(response.body)
239
198
  raise_with_response response
240
199
  end
241
200
 
242
- response.body == 'true'
201
+ [
202
+ response.body == 'true',
203
+ response['X-akismet-pro-tip'] == 'discard'
204
+ ]
243
205
  end
206
+ alias_method :comment_check, :check
244
207
 
245
-
246
- # Submits a comment that has been identified as not-spam (ham). Takes
247
- # the same arguments as {#comment_check}. If the Client is not open, opens
248
- # it for the duration of the call.
208
+ # Checks whether a comment is spam.
209
+ # @!macro akismet_method
210
+ # @return [Boolean]
249
211
  #
250
- # @return [nil]
251
- # @raise [Akismet::Error]
252
- # @see #comment_check
212
+ def spam?(user_ip, user_agent, params = {})
213
+ check(user_ip, user_agent, params)[0]
214
+ end
215
+
216
+ # @!group Reporting
217
+
218
+ # Submits a comment that has been identified as not-spam (ham).
219
+ # @!macro akismet_method
220
+ # @return [void]
253
221
  #
254
- def submit_ham( user_ip, user_agent, params = {} )
255
- response = invoke_comment_method( 'submit-ham',
222
+ def ham(user_ip, user_agent, params = {})
223
+ response = invoke_comment_method('submit-ham',
256
224
  user_ip,
257
225
  user_agent,
258
- params )
226
+ params)
259
227
 
260
228
  unless response.body == 'Thanks for making the web a better place.'
261
229
  raise_with_response response
262
230
  end
263
-
264
- nil
265
231
  end
232
+ alias_method :submit_ham, :ham
266
233
 
267
-
268
- # Submits a comment that has been identified as spam. Takes the same
269
- # arguments as {#comment_check}. If the Client is not open, opens it for
270
- # the duration of the call.
234
+ # Submits a comment that has been identified as spam.
235
+ # @!macro akismet_method
236
+ # @return [void]
271
237
  #
272
- # @return [nil]
273
- # @raise [Akismet::Error]
274
- # @see #comment_check
275
- #
276
- def submit_spam( user_ip, user_agent, params = {} )
277
- response = invoke_comment_method( 'submit-spam',
238
+ def spam(user_ip, user_agent, params = {})
239
+ response = invoke_comment_method('submit-spam',
278
240
  user_ip,
279
241
  user_agent,
280
- params )
242
+ params)
281
243
 
282
244
  unless response.body == 'Thanks for making the web a better place.'
283
245
  raise_with_response response
284
246
  end
285
-
286
- nil
287
247
  end
248
+ alias_method :submit_spam, :spam
288
249
 
289
250
 
290
- private
251
+ private
291
252
 
292
253
 
293
254
  # Yields an HTTP session to the given block. Uses this instance's open
@@ -296,54 +257,49 @@ module Akismet
296
257
  # @yield [Net::HTTP]
297
258
  #
298
259
  def in_http_session
299
- raise "Block required" unless block_given?
300
260
  if open?
301
261
  yield @http_session
302
262
  else
303
- begin
304
- open
305
- yield @http_session
306
- ensure
307
- close
308
- end
263
+ open { yield @http_session }
309
264
  end
310
265
  end
311
266
 
312
-
313
- # Raises an error given a response. The Akismet documentation states that
314
- # the HTTP headers of the response may contain error strings. I can't
315
- # seem to find them, so for now just raise an unknown error.
316
267
  # @param [Net::HTTPResponse] response
317
- #
318
268
  def raise_with_response( response )
319
- raise Error.new( Error::UNKNOWN, 'Unknown error' )
269
+ raise Error, response['X-akismet-debug-help'] || 'Unknown error'
320
270
  end
321
271
 
322
-
323
272
  # @param [String] method_name
324
273
  # @param [String] user_ip
325
274
  # @param [String] user_agent
326
275
  # @param [Hash] params
327
276
  # @return [Net::HTTPResponse]
328
- # @raise [Akismet::Error]
329
- # The API key is invalid.
277
+ # @raise [ArgumentError]
278
+ # An environment variable conflicts with a built-in parameter
279
+ # @raise [ArgumentError]
280
+ # Invalid parameter
330
281
  #
331
- def invoke_comment_method( method_name, user_ip, user_agent, params = {} )
332
- params = params.merge :blog => home_url,
333
- :user_ip => user_ip,
334
- :user_agent => user_agent
282
+ def invoke_comment_method(method_name, user_ip, user_agent, params = {})
283
+ env = params[:env] || {}
335
284
 
336
- response = in_http_session do |session|
337
- invoke( session, method_name, params )
285
+ for key in env.keys
286
+ if PARAM_TO_API_PARAM.has_value?(key.to_sym)
287
+ raise ArgumentError, "Environment variable '#{key}' conflicts with built-in API parameter"
288
+ end
338
289
  end
339
290
 
340
- if response.body == 'invalid'
341
- raise Error.new( Error::INVALID_API_KEY, 'Invalid API key' )
291
+ params = params.each_with_object(Hash.new) do |(name, value), api_params|
292
+ next if name == :env
293
+ api_name = PARAM_TO_API_PARAM[name] || raise(ArgumentError, "Invalid param: #{name}")
294
+ api_params[api_name] = value
342
295
  end
343
296
 
344
- response
345
- end
297
+ params = env.merge(params).merge(blog: app_url, user_ip: user_ip, user_agent: user_agent)
346
298
 
299
+ in_http_session do |session|
300
+ invoke session, method_name, params
301
+ end
302
+ end
347
303
 
348
304
  # @param [Net::HTTP] http_session
349
305
  # A started HTTP session
@@ -352,10 +308,16 @@ module Akismet
352
308
  # @raise [Akismet::Error]
353
309
  # An HTTP response other than 200 is received.
354
310
  #
355
- def invoke( http_session, method_name, params = {} )
356
- response = http_session.post( "/1.1/#{ method_name }",
357
- url_encode( params ),
358
- http_headers )
311
+ def invoke(http_session, method_name, params = {})
312
+ params[:blog_charset] = 'UTF-8'
313
+
314
+ params = params.collect do |name, value|
315
+ [name.to_s.encode('UTF-8'), format(value).encode('UTF-8')]
316
+ end
317
+
318
+ response = http_session.post("/1.1/#{ method_name }",
319
+ URI.encode_www_form(params),
320
+ http_headers)
359
321
 
360
322
  unless response.is_a?( Net::HTTPOK )
361
323
  raise Error, "HTTP #{ response.code } received (expected 200)"
@@ -364,46 +326,66 @@ module Akismet
364
326
  response
365
327
  end
366
328
 
329
+ # @param [Object] object
330
+ # @return [String]
331
+ def format(object)
332
+ case object
333
+ when DateTime
334
+ object.iso8601
335
+ when TrueClass
336
+ '1'
337
+ when FalseClass
338
+ '0'
339
+ when Array
340
+ object.collect { |element| format(element) }.join(', ')
341
+ else
342
+ object.to_s
343
+ end
344
+ end
367
345
 
368
346
  # @return [Hash]
369
- #
370
347
  def http_headers
371
- { 'User-Agent' => user_agent }
348
+ {
349
+ 'User-Agent' => user_agent,
350
+ 'Content-Type' => 'application/x-www-form-urlencoded'
351
+ }
372
352
  end
373
353
 
374
-
375
- # @return [String]
376
- #
377
- def url_encode( hash = {} )
378
- hash.collect do |k, v|
379
- "#{ CGI.escape( k.to_s ) }=#{ CGI.escape( v.to_s ) }"
380
- end.join( "&" )
381
- end
382
-
383
-
384
354
  # From the Akismet documentation:
385
355
  # If possible, your user agent string should always use the following
386
356
  # format: Application Name/Version | Plugin Name/Version
387
357
  # @return [String]
388
358
  #
389
359
  def user_agent
390
- [ user_agent_app, user_agent_plugin ].compact.join( " | " )
360
+ [user_agent_app, user_agent_plugin].compact.join(" | ")
391
361
  end
392
362
 
393
-
394
363
  # Returns nil if the Client was instantiated without an app_name.
395
364
  # @return [String]
396
365
  #
397
366
  def user_agent_app
398
- app_name && [ app_name, app_version ].compact.join( "/" )
367
+ app_name && [app_name, app_version].compact.join("/")
399
368
  end
400
369
 
401
-
402
370
  # @return [String]
403
- #
404
371
  def user_agent_plugin
405
372
  "Ruby Akismet/#{ Akismet::VERSION }"
406
373
  end
407
374
 
375
+ PARAM_TO_API_PARAM = {
376
+ referrer: :referrer,
377
+ post_url: :permalink,
378
+ post_modified_at: :comment_post_modified_gmt,
379
+ text: :comment_content,
380
+ created_at: :comment_date_gmt,
381
+ type: :comment_type,
382
+ author: :comment_author,
383
+ author_url: :comment_author_url,
384
+ author_email: :comment_author_email,
385
+ languages: :blog_lang,
386
+ user_role: :user_role,
387
+ test: :is_test,
388
+ }
389
+
408
390
  end
409
- end
391
+ end
@@ -1,23 +1,6 @@
1
1
  module Akismet
2
2
 
3
3
  class Error < StandardError
4
-
5
- UNKNOWN = 1
6
- INVALID_API_KEY = 2
7
-
8
- # An error code corresponding to a constant in Akismet::Error.
9
- # @return [Integer]
10
- attr_reader :code
11
-
12
- # @param [String] message
13
- # A human-readable description of the error.
14
- # @param [Integer] code
15
- # An error code corresponding to a constant in Akismet::Error.
16
- #
17
- def initialize( code, message = nil )
18
- super( message )
19
- @code = code
20
- end
21
4
  end
22
5
 
23
- end
6
+ end
@@ -1,6 +1,6 @@
1
1
  module Akismet
2
2
  # The version of the Akismet gem.
3
- VERSION = '1.0.2'
3
+ VERSION = '2.0.0'
4
4
 
5
5
  # The supported version of the Akismet API.
6
6
  API_VERSION = '1.3'
metadata CHANGED
@@ -1,22 +1,66 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: akismet
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonah Burke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-07 00:00:00.000000000 Z
12
- dependencies: []
13
- description: A Ruby client for the Akismet API
14
- email: jonah@jonahb.com
11
+ date: 2015-02-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.8.7
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.8.7
55
+ description:
56
+ email:
57
+ - jonah@jonahb.com
15
58
  executables: []
16
59
  extensions: []
17
60
  extra_rdoc_files: []
18
61
  files:
19
- - MIT-LICENSE
62
+ - ".yardopts"
63
+ - LICENSE.txt
20
64
  - README.md
21
65
  - lib/akismet.rb
22
66
  - lib/akismet/client.rb
@@ -34,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
34
78
  requirements:
35
79
  - - ">="
36
80
  - !ruby/object:Gem::Version
37
- version: '0'
81
+ version: 1.9.3
38
82
  required_rubygems_version: !ruby/object:Gem::Requirement
39
83
  requirements:
40
84
  - - ">="
@@ -42,8 +86,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
42
86
  version: '0'
43
87
  requirements: []
44
88
  rubyforge_project:
45
- rubygems_version: 2.4.3
89
+ rubygems_version: 2.4.5
46
90
  signing_key:
47
91
  specification_version: 4
48
92
  summary: A Ruby client for the Akismet API
49
93
  test_files: []
94
+ has_rdoc: