spamster 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +63 -19
- data/lib/spamster.rb +47 -20
- data/lib/spamster/model.rb +23 -0
- data/lib/spamster/model/proxy.rb +29 -0
- data/lib/spamster/rack/middleware.rb +22 -0
- data/lib/spamster/version.rb +1 -1
- data/spamster.gemspec +3 -2
- data/spec/spamster/model_spec.rb +44 -0
- data/spec/spamster/rack/middleware_spec.rb +33 -0
- data/spec/spamster_spec.rb +29 -8
- metadata +34 -4
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Spamster [![Build Status](https://secure.travis-ci.org/balexand/spamster.png)](http://travis-ci.org/balexand/spamster)
|
2
2
|
|
3
|
-
Simple spam filtering.
|
3
|
+
Simple spam filtering that works with any Ruby application and can be set up in minutes. It does not depend on any specific ORM or framework, although it includes optional Rack middleware. It uses Akismet or TypePad AntiSpam.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -14,29 +14,75 @@ And then execute:
|
|
14
14
|
|
15
15
|
$ bundle
|
16
16
|
|
17
|
-
|
17
|
+
## Usage
|
18
18
|
|
19
|
-
|
19
|
+
### Configuration
|
20
20
|
|
21
|
-
|
21
|
+
First you'll need to sign up for an API key from [Akismet](https://akismet.com/signup/) or [TypePad AntiSpam](http://antispam.typepad.com/info/get-api-key.html). Then configure Spamster like:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
Spamster.use_akismet("your-api-key", "http://yoursite.com/")
|
25
|
+
```
|
26
|
+
|
27
|
+
or...
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
Spamster.use_typepad("your-api-key", "http://yoursite.com/")
|
31
|
+
```
|
32
|
+
|
33
|
+
If you're building a Rack app (all Rails 3+ apps are Rack apps), then you'll probably want to use the optional Rack middleware so Spamster can automatically fill in the `referrer`, `user_agent`, and `user_ip` params. If you're using Rails then add the middleware like this:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
Rails.application.config.middleware.use Spamster::Rack::Middleware
|
37
|
+
```
|
38
|
+
|
39
|
+
If you're using Rails, then a suggested location to keep the above configuration is in an initializer file.
|
40
|
+
|
41
|
+
### Sanity check
|
22
42
|
|
23
|
-
|
43
|
+
First check that your key is valid:
|
24
44
|
|
25
|
-
|
45
|
+
```ruby
|
46
|
+
Spamster.key_valid? # => true
|
47
|
+
```
|
48
|
+
|
49
|
+
Then check that it detects spam using the name `viagra-test-123`:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
Spamster.spam?(user_ip: "222.222.222.222", user_agent: "Mozilla", comment_author: "viagra-test-123") # => true
|
53
|
+
```
|
54
|
+
|
55
|
+
And if you want to see the HTTP requests/responses while debugging:
|
26
56
|
|
27
57
|
```ruby
|
28
|
-
Spamster.
|
29
|
-
Spamster.key = "your-api-key"
|
58
|
+
Spamster.debug_output = $stderr
|
30
59
|
```
|
31
60
|
|
32
|
-
|
33
|
-
|
61
|
+
### Model mixin
|
62
|
+
|
63
|
+
The easiest way to use Spamster is to include the mixin in your comment model:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
class Comment
|
67
|
+
attr_accessor :content, :email, :name
|
68
|
+
|
69
|
+
include Spamster::Model
|
70
|
+
spamster_attrs comment_author: :name, comment_author_email: :email, comment_content: :content
|
71
|
+
end
|
72
|
+
|
73
|
+
comment = Comment.new #...
|
74
|
+
comment.spamster.spam? # checks for spam
|
75
|
+
comment.spamster.spam! # reports a false negative
|
76
|
+
comment.spamster.ham! # reports a false positive
|
77
|
+
```
|
78
|
+
|
79
|
+
For a full list of parameters accepted by `spamster_attrs`, see [Akismet's documentation for `comment-check`](http://akismet.com/development/api/#comment-check).
|
34
80
|
|
35
81
|
### Spamster methods
|
36
82
|
|
37
83
|
#### key_valid?
|
38
84
|
|
39
|
-
Checks if the key is valid using [verify-key](http://akismet.com/development/api/#verify-key).
|
85
|
+
Checks if the key is valid using [`verify-key`](http://akismet.com/development/api/#verify-key).
|
40
86
|
|
41
87
|
```ruby
|
42
88
|
Spamster.key_valid?
|
@@ -44,7 +90,7 @@ Spamster.key_valid?
|
|
44
90
|
|
45
91
|
#### spam?
|
46
92
|
|
47
|
-
Checks if a comment is spam using [comment-check](http://akismet.com/development/api/#comment-check)
|
93
|
+
Checks if a comment is spam using [`comment-check`](http://akismet.com/development/api/#comment-check).
|
48
94
|
|
49
95
|
```ruby
|
50
96
|
Spamster.spam?(user_ip: "222.222.222.222", user_agent: "Mozilla", comment_author: "viagra-test-123")
|
@@ -52,7 +98,7 @@ Spamster.spam?(user_ip: "222.222.222.222", user_agent: "Mozilla", comment_author
|
|
52
98
|
|
53
99
|
### spam!
|
54
100
|
|
55
|
-
Reports a false negative using [submit-spam](http://akismet.com/development/api/#submit-spam)
|
101
|
+
Reports a false negative using [`submit-spam`](http://akismet.com/development/api/#submit-spam).
|
56
102
|
|
57
103
|
```ruby
|
58
104
|
Spamster.spam!(user_ip: "222.222.222.222", user_agent: "Mozilla", comment_author: "viagra-test-123")
|
@@ -60,7 +106,7 @@ Spamster.spam!(user_ip: "222.222.222.222", user_agent: "Mozilla", comment_author
|
|
60
106
|
|
61
107
|
### ham!
|
62
108
|
|
63
|
-
Reports a false positive using [submit-ham](http://akismet.com/development/api/#submit-ham)
|
109
|
+
Reports a false positive using [`submit-ham`](http://akismet.com/development/api/#submit-ham).
|
64
110
|
|
65
111
|
```ruby
|
66
112
|
Spamster.ham!(user_ip: "222.222.222.222", user_agent: "Mozilla", comment_author: "viagra-test-123")
|
@@ -68,8 +114,6 @@ Spamster.ham!(user_ip: "222.222.222.222", user_agent: "Mozilla", comment_author:
|
|
68
114
|
|
69
115
|
## Contributing
|
70
116
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
75
|
-
5. Create new Pull Request
|
117
|
+
Fork it, install dependencies with `bundle`, and run tests with `bundle exec rake`. If you submit a pull request, then remember to include tests.
|
118
|
+
|
119
|
+
Created by Brian Alexander and released under an MIT License.
|
data/lib/spamster.rb
CHANGED
@@ -1,54 +1,81 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
1
3
|
require 'net/http'
|
2
4
|
require 'spamster/version'
|
5
|
+
require 'uri'
|
3
6
|
|
4
7
|
module Spamster
|
8
|
+
autoload :Model, 'spamster/model'
|
9
|
+
autoload :Rack, 'spamster/rack/middleware'
|
10
|
+
|
5
11
|
class <<self
|
6
|
-
attr_accessor :blog, :key
|
12
|
+
attr_accessor :api_host, :blog, :debug_output, :key, :request_params
|
13
|
+
|
14
|
+
def use_akismet(key, blog)
|
15
|
+
self.api_host = "rest.akismet.com"
|
16
|
+
self.blog = blog
|
17
|
+
self.key = key
|
18
|
+
end
|
19
|
+
|
20
|
+
def use_typepad(key, blog)
|
21
|
+
self.api_host = "api.antispam.typepad.com"
|
22
|
+
self.blog = blog
|
23
|
+
self.key = key
|
24
|
+
end
|
7
25
|
|
8
26
|
# see http://akismet.com/development/api/#verify-key
|
9
27
|
def key_valid?
|
10
|
-
check_config
|
11
28
|
params = {:blog => blog, :key => key}
|
12
|
-
response =
|
29
|
+
response = perform_post("http://#{api_host}/1.1/verify-key", params)
|
13
30
|
response.body == 'valid'
|
14
31
|
end
|
15
32
|
|
16
33
|
# see http://akismet.com/development/api/#comment-check
|
17
34
|
def spam?(params)
|
18
|
-
|
35
|
+
perform_spam_post("comment-check", params) == 'true'
|
19
36
|
end
|
20
37
|
|
21
38
|
# see http://akismet.com/development/api/#submit-spam
|
22
39
|
def spam!(params)
|
23
|
-
|
40
|
+
perform_spam_post("submit-spam", params)
|
24
41
|
end
|
25
42
|
|
26
43
|
# see http://akismet.com/development/api/#submit-ham
|
27
44
|
def ham!(params)
|
28
|
-
|
45
|
+
perform_spam_post("submit-ham", params)
|
29
46
|
end
|
30
47
|
|
31
48
|
private
|
32
|
-
def
|
33
|
-
|
34
|
-
|
49
|
+
def perform_post(url, params)
|
50
|
+
[:api_host, :blog, :key].each do |param|
|
51
|
+
raise "'Spamster.#{param}' must be set" unless send(param).present?
|
52
|
+
end
|
53
|
+
|
54
|
+
uri = URI(url)
|
55
|
+
|
56
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
57
|
+
http.set_debug_output(debug_output) if debug_output
|
58
|
+
|
59
|
+
req = Net::HTTP::Post.new(uri.path)
|
60
|
+
req.set_form_data(params)
|
61
|
+
# Akismet wants User-Agent format: Application Name/Version | Plugin Name/Version
|
62
|
+
user_agent = "Spamster/#{VERSION}"
|
63
|
+
user_agent = "Rails/#{Rails.version} | " + user_agent if defined?(Rails)
|
64
|
+
req['User-Agent'] = user_agent
|
65
|
+
|
66
|
+
http.start { |h| h.request(req) }
|
35
67
|
end
|
36
68
|
|
37
|
-
|
38
|
-
|
69
|
+
# checks params and performs post for spam?, spam!, and ham!
|
70
|
+
def perform_spam_post(method, params = {})
|
71
|
+
params = params.merge(:blog => blog)
|
72
|
+
params.merge!(request_params) if request_params
|
39
73
|
[:blog, :user_agent, :user_ip].each do |param|
|
40
|
-
raise "required param #{param.inspect} is missing" unless params[param]
|
74
|
+
raise "required param #{param.inspect} is missing" unless params[param].present?
|
41
75
|
end
|
42
|
-
end
|
43
76
|
|
44
|
-
|
45
|
-
check_config
|
46
|
-
params = params.merge(:blog => blog)
|
47
|
-
check_required_params(params)
|
48
|
-
response = Net::HTTP.post_form(URI("http://#{key}.rest.akismet.com/1.1/#{method}"), params)
|
77
|
+
response = perform_post("http://#{key}.#{api_host}/1.1/#{method}", params)
|
49
78
|
response.body
|
50
79
|
end
|
51
80
|
end
|
52
81
|
end
|
53
|
-
|
54
|
-
# FIXME User-Agent
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'spamster/model/proxy'
|
3
|
+
|
4
|
+
module Spamster
|
5
|
+
module Model
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
spamster_attrs({})
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def spamster_attrs(attrs = nil)
|
14
|
+
@spamster_attrs = attrs if attrs
|
15
|
+
@spamster_attrs
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def spamster
|
20
|
+
Proxy.new(self)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Spamster
|
2
|
+
module Model
|
3
|
+
class Proxy
|
4
|
+
def initialize(model)
|
5
|
+
@model = model
|
6
|
+
end
|
7
|
+
|
8
|
+
def spam?
|
9
|
+
Spamster.spam?(data)
|
10
|
+
end
|
11
|
+
|
12
|
+
def spam!
|
13
|
+
Spamster.spam!(data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def ham!
|
17
|
+
Spamster.ham!(data)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def data
|
22
|
+
Hash[@model.class.spamster_attrs.map do |param, method|
|
23
|
+
[param, @model.send(method)]
|
24
|
+
end]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Spamster
|
2
|
+
module Rack
|
3
|
+
class Middleware
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
params = {}
|
10
|
+
params[:referrer] = env['HTTP_REFERER'] if env['HTTP_REFERER']
|
11
|
+
params[:user_agent] = env['HTTP_USER_AGENT'] if env['HTTP_USER_AGENT']
|
12
|
+
params[:user_ip] = env['REMOTE_ADDR'] if env['REMOTE_ADDR']
|
13
|
+
Spamster.request_params = params
|
14
|
+
|
15
|
+
response = @app.call(env)
|
16
|
+
|
17
|
+
Spamster.request_params = nil
|
18
|
+
response
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/spamster/version.rb
CHANGED
data/spamster.gemspec
CHANGED
@@ -4,8 +4,8 @@ require File.expand_path('../lib/spamster/version', __FILE__)
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.authors = ["Brian Alexander"]
|
6
6
|
gem.email = ["balexand@gmail.com"]
|
7
|
-
gem.description = %q{Simple spam filtering that
|
8
|
-
gem.summary = %q{Simple spam filtering.}
|
7
|
+
gem.description = %q{Simple spam filtering that works with any Ruby application and can be set up in minutes. Uses Akismet or TypePad AntiSpam.}
|
8
|
+
gem.summary = %q{Simple spam filtering using Akismet or TypePad AntiSpam.}
|
9
9
|
gem.homepage = "https://github.com/balexand/spamster"
|
10
10
|
|
11
11
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
@@ -19,5 +19,6 @@ Gem::Specification.new do |gem|
|
|
19
19
|
gem.add_development_dependency "rspec"
|
20
20
|
gem.add_development_dependency "webmock"
|
21
21
|
|
22
|
+
gem.add_runtime_dependency "activesupport"
|
22
23
|
gem.add_runtime_dependency "jruby-openssl" if RUBY_PLATFORM == "java"
|
23
24
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Comment
|
4
|
+
include Spamster::Model
|
5
|
+
spamster_attrs :comment_author => :name, :comment_author_email => :email, :comment_content => :content
|
6
|
+
attr_accessor :content, :email, :name
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Spamster::Model do
|
10
|
+
let(:comment) do
|
11
|
+
Comment.new.tap do |c|
|
12
|
+
c.content = "hello world"
|
13
|
+
c.email = "test@example.com"
|
14
|
+
c.name = "John"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "spamster.data" do
|
19
|
+
it "should get correct params from model" do
|
20
|
+
comment.spamster.send(:data).should == {:comment_author => "John", :comment_author_email => "test@example.com", :comment_content => "hello world"}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "spamster.spam?" do
|
25
|
+
it "should pass params from model" do
|
26
|
+
Spamster.should_receive(:spam?).once.with(:comment_author => "John", :comment_author_email => "test@example.com", :comment_content => "hello world")
|
27
|
+
comment.spamster.spam?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "spamster.spam!" do
|
32
|
+
it "should pass params from model" do
|
33
|
+
Spamster.should_receive(:spam!).once.with(:comment_author => "John", :comment_author_email => "test@example.com", :comment_content => "hello world")
|
34
|
+
comment.spamster.spam!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "spamster.ham!" do
|
39
|
+
it "should pass params from model" do
|
40
|
+
Spamster.should_receive(:ham!).once.with(:comment_author => "John", :comment_author_email => "test@example.com", :comment_content => "hello world")
|
41
|
+
comment.spamster.ham!
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spamster::Rack::Middleware do
|
4
|
+
before(:each) do
|
5
|
+
Spamster.use_akismet("123abc", "http://example.com/")
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "call" do
|
9
|
+
it "should set 'referrer', 'user_agent', and 'user_ip' request_params" do
|
10
|
+
stub_request(:post, "http://123abc.rest.akismet.com/1.1/comment-check")
|
11
|
+
|
12
|
+
app = Object.new
|
13
|
+
app.stub(:call) do |env|
|
14
|
+
Spamster.request_params.should == {
|
15
|
+
:referrer => 'http://referer.com/',
|
16
|
+
:user_agent => 'Mozillaish',
|
17
|
+
:user_ip => "123.123.123.123"
|
18
|
+
}
|
19
|
+
|
20
|
+
Spamster.spam?(:comment_author => "Test User")
|
21
|
+
end
|
22
|
+
app.should_receive(:call).once
|
23
|
+
Spamster::Rack::Middleware.new(app).call(
|
24
|
+
'HTTP_REFERER' => 'http://referer.com/', 'HTTP_USER_AGENT' => 'Mozillaish', 'REMOTE_ADDR' => '123.123.123.123'
|
25
|
+
)
|
26
|
+
Spamster.request_params.should be_nil
|
27
|
+
|
28
|
+
assert_requested(:post, "http://123abc.rest.akismet.com/1.1/comment-check", :times => 1) do |req|
|
29
|
+
CGI.parse(req.body).should == {"comment_author"=>["Test User"], "blog"=>["http://example.com/"], "referrer"=>["http://referer.com/"], "user_agent"=>["Mozillaish"], "user_ip"=>["123.123.123.123"]}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/spamster_spec.rb
CHANGED
@@ -2,28 +2,49 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Spamster do
|
4
4
|
before(:each) do
|
5
|
-
Spamster.
|
6
|
-
Spamster.key = "123abc"
|
5
|
+
Spamster.use_akismet("123abc", "http://example.com/")
|
7
6
|
end
|
8
7
|
|
9
|
-
describe "
|
8
|
+
describe "perform_post" do
|
10
9
|
before(:each) do
|
11
10
|
stub_request(:post, "http://123abc.rest.akismet.com/1.1/comment-check")
|
12
11
|
end
|
13
12
|
|
13
|
+
it "should raise exception if :api_host is not configured" do
|
14
|
+
Spamster.api_host = ""
|
15
|
+
expect do
|
16
|
+
Spamster.send(:perform_post, "http://123abc.rest.akismet.com/1.1/comment-check", {})
|
17
|
+
end.to raise_exception{ |e| e.message.should == "'Spamster.api_host' must be set" }
|
18
|
+
end
|
19
|
+
|
14
20
|
it "should raise exception if :blog is not configured" do
|
15
|
-
Spamster.blog =
|
21
|
+
Spamster.blog = ""
|
16
22
|
expect do
|
17
|
-
Spamster.send(:
|
23
|
+
Spamster.send(:perform_post, "http://123abc.rest.akismet.com/1.1/comment-check", {})
|
18
24
|
end.to raise_exception{ |e| e.message.should == "'Spamster.blog' must be set" }
|
19
25
|
end
|
20
26
|
|
21
27
|
it "should raise exception if :key is not configured" do
|
22
|
-
Spamster.key =
|
28
|
+
Spamster.key = " \n"
|
23
29
|
expect do
|
24
|
-
Spamster.send(:
|
30
|
+
Spamster.send(:perform_post, "http://123abc.rest.akismet.com/1.1/comment-check", {})
|
25
31
|
end.to raise_exception{ |e| e.message.should == "'Spamster.key' must be set" }
|
26
32
|
end
|
33
|
+
|
34
|
+
it "should set User-Agent" do
|
35
|
+
Spamster.send(:perform_post, "http://123abc.rest.akismet.com/1.1/comment-check", {})
|
36
|
+
assert_requested(:post, "http://123abc.rest.akismet.com/1.1/comment-check", :times => 1, :headers => {'User-Agent' => "Spamster/#{Spamster::VERSION}"})
|
37
|
+
|
38
|
+
class Rails
|
39
|
+
def self.version
|
40
|
+
"3.2.2"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Spamster.send(:perform_post, "http://123abc.rest.akismet.com/1.1/comment-check", {})
|
45
|
+
assert_requested(:post, "http://123abc.rest.akismet.com/1.1/comment-check", :times => 1, :headers => {'User-Agent' => "Rails/3.2.2 | Spamster/#{Spamster::VERSION}"})
|
46
|
+
Object.send(:remove_const, :Rails)
|
47
|
+
end
|
27
48
|
end
|
28
49
|
|
29
50
|
describe "key_valid?" do
|
@@ -67,7 +88,7 @@ describe Spamster do
|
|
67
88
|
|
68
89
|
it "should raise exception if required param missing" do
|
69
90
|
expect do
|
70
|
-
Spamster.spam?(:user_ip => "222.222.222.222")
|
91
|
+
Spamster.spam?(:user_agent => " ", :user_ip => "222.222.222.222")
|
71
92
|
end.to raise_exception{ |e| e.message.should == "required param :user_agent is missing" }
|
72
93
|
|
73
94
|
expect do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spamster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -59,7 +59,24 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
-
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: activesupport
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Simple spam filtering that works with any Ruby application and can be
|
79
|
+
set up in minutes. Uses Akismet or TypePad AntiSpam.
|
63
80
|
email:
|
64
81
|
- balexand@gmail.com
|
65
82
|
executables: []
|
@@ -73,8 +90,13 @@ files:
|
|
73
90
|
- README.md
|
74
91
|
- Rakefile
|
75
92
|
- lib/spamster.rb
|
93
|
+
- lib/spamster/model.rb
|
94
|
+
- lib/spamster/model/proxy.rb
|
95
|
+
- lib/spamster/rack/middleware.rb
|
76
96
|
- lib/spamster/version.rb
|
77
97
|
- spamster.gemspec
|
98
|
+
- spec/spamster/model_spec.rb
|
99
|
+
- spec/spamster/rack/middleware_spec.rb
|
78
100
|
- spec/spamster_spec.rb
|
79
101
|
- spec/spec_helper.rb
|
80
102
|
homepage: https://github.com/balexand/spamster
|
@@ -89,18 +111,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
111
|
- - ! '>='
|
90
112
|
- !ruby/object:Gem::Version
|
91
113
|
version: '0'
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
hash: -3161924574973985912
|
92
117
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
118
|
none: false
|
94
119
|
requirements:
|
95
120
|
- - ! '>='
|
96
121
|
- !ruby/object:Gem::Version
|
97
122
|
version: '0'
|
123
|
+
segments:
|
124
|
+
- 0
|
125
|
+
hash: -3161924574973985912
|
98
126
|
requirements: []
|
99
127
|
rubyforge_project:
|
100
128
|
rubygems_version: 1.8.19
|
101
129
|
signing_key:
|
102
130
|
specification_version: 3
|
103
|
-
summary: Simple spam filtering.
|
131
|
+
summary: Simple spam filtering using Akismet or TypePad AntiSpam.
|
104
132
|
test_files:
|
133
|
+
- spec/spamster/model_spec.rb
|
134
|
+
- spec/spamster/rack/middleware_spec.rb
|
105
135
|
- spec/spamster_spec.rb
|
106
136
|
- spec/spec_helper.rb
|