akismet 1.0.2 → 2.0.0

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.
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: